All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
@ 2007-05-07 21:41 George S. Coker, II
  2007-05-07 23:10 ` Chris Wright
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-07 21:41 UTC (permalink / raw)
  To: xen-devel, xense-devel

[-- Attachment #1: Type: text/plain, Size: 271 bytes --]

Updates in this patch set include:
    - adaptation to new create secure interface for domain_create
    - cleanup of xsm enable/disable framework through xsm_call macro
    - ifdef architecture/config specific hooks

Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>

[-- Attachment #2: xsm-050707-xen-15011.diff --]
[-- Type: text/x-patch, Size: 78161 bytes --]

diff -r e370c94bd6fd -r 62b752969edf Config.mk
--- a/Config.mk	Sat May 05 13:48:05 2007 +0100
+++ b/Config.mk	Mon May 07 14:50:16 2007 -0400
@@ -72,6 +72,10 @@ 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 ?= y
+
 # 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
diff -r e370c94bd6fd -r 62b752969edf linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Sat May 05 13:48:05 2007 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Mon May 07 14:50:16 2007 -0400
@@ -402,6 +402,12 @@ HYPERVISOR_kexec_op(
 	return _hypercall2(int, kexec_op, op, args);
 }
 
+static inline int
+HYPERVISOR_xsm_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, xsm_op, cmd, arg);
+}
 
 
 #endif /* __HYPERCALL_H__ */
diff -r e370c94bd6fd -r 62b752969edf linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Sat May 05 13:48:05 2007 +0100
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Mon May 07 14:50:16 2007 -0400
@@ -403,4 +403,11 @@ HYPERVISOR_kexec_op(
 	return _hypercall2(int, kexec_op, op, args);
 }
 
+static inline int
+HYPERVISOR_xsm_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, xsm_op, cmd, arg);
+}
+
 #endif /* __HYPERCALL_H__ */
diff -r e370c94bd6fd -r 62b752969edf xen/Makefile
--- a/xen/Makefile	Sat May 05 13:48:05 2007 +0100
+++ b/xen/Makefile	Mon May 07 14:50:16 2007 -0400
@@ -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
@@ -138,7 +139,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 e370c94bd6fd -r 62b752969edf xen/Rules.mk
--- a/xen/Rules.mk	Sat May 05 13:48:05 2007 +0100
+++ b/xen/Rules.mk	Mon May 07 14:50:16 2007 -0400
@@ -47,10 +47,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 e370c94bd6fd -r 62b752969edf xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/domctl.c	Mon May 07 14:50:16 2007 -0400
@@ -25,6 +25,7 @@
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
 #include <public/hvm/e820.h>
+#include <xsm/xsm.h>
 
 long arch_do_domctl(
     struct xen_domctl *domctl,
@@ -42,6 +43,13 @@ long arch_do_domctl(
         d = rcu_lock_domain_by_id(domctl->domain);
         if ( d != NULL )
         {
+            ret = xsm_shadow_control(d, domctl->u.shadow_op.op);
+            if ( ret )
+            {
+                rcu_unlock_domain(d);
+                break;
+            }
+
             ret = paging_domctl(d,
                                 &domctl->u.shadow_op,
                                 guest_handle_cast(u_domctl, void));
@@ -64,6 +72,13 @@ 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;
@@ -88,6 +103,13 @@ long arch_do_domctl(
         if ( unlikely(!mfn_valid(mfn)) ||
              unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
             break;
+
+        ret = xsm_getpageframeinfo(mfn);
+        if ( ret )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
 
         page = mfn_to_page(mfn);
 
@@ -172,6 +194,10 @@ long arch_do_domctl(
                 struct page_info *page;
                 unsigned long mfn = arr32[j];
 
+                ret = xsm_getpageframeinfo(mfn);
+                if ( ret )
+                    continue;
+
                 page = mfn_to_page(mfn);
 
                 if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 
@@ -231,6 +257,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);
@@ -270,6 +303,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 +344,10 @@ long arch_do_domctl(
         ret = -ESRCH;
         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) ) 
@@ -336,6 +380,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;
@@ -387,6 +435,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
@@ -413,6 +468,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 e370c94bd6fd -r 62b752969edf xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c	Mon May 07 14:50:16 2007 -0400
@@ -1,3 +1,4 @@
+
 /*
  * hvm.c: Common hardware virtual machine abstractions.
  *
@@ -896,6 +897,10 @@ static int hvmop_set_pci_intx_level(
     if ( d == NULL )
         return -ESRCH;
 
+    rc = xsm_hvm_set_pci_intx_level(d);
+    if ( rc )
+        goto out;
+
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
         goto out;
@@ -939,6 +944,10 @@ static int hvmop_set_isa_irq_level(
     if ( d == NULL )
         return -ESRCH;
 
+    rc = xsm_hvm_set_isa_irq_level(d);
+    if ( rc )
+        goto out;
+
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
         goto out;
@@ -981,6 +990,10 @@ static int hvmop_set_pci_link_route(
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = xsm_hvm_set_pci_link_route(d);
+    if ( rc )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -1024,6 +1037,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
 
         if ( d == NULL )
             return -ESRCH;
+
+        rc = xsm_hvm_param(d, op);
+        if ( rc )
+            goto param_fail;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
diff -r e370c94bd6fd -r 62b752969edf xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/irq.c	Mon May 07 14:50:16 2007 -0400
@@ -16,6 +16,7 @@
 #include <xen/compat.h>
 #include <asm/current.h>
 #include <asm/smpboot.h>
+#include <xsm/xsm.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
 int opt_noirqbalance = 0;
@@ -333,6 +334,9 @@ int pirq_guest_unmask(struct domain *d)
           irq < NR_IRQS;
           irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
     {
+        if ( xsm_pirq_unmask(d, irq) )
+            continue;
+
         if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) )
             __pirq_guest_eoi(d, irq);
     }
diff -r e370c94bd6fd -r 62b752969edf xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/mm.c	Mon May 07 14:50:16 2007 -0400
@@ -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)
 
@@ -2029,6 +2030,10 @@ int do_mmuext_op(
             type = PGT_l4_page_table;
 
         pin_page:
+            rc = xsm_memory_pin_page(current->domain, mfn);
+            if ( rc )
+                break;
+
             /* Ignore pinning of invalid paging levels. */
             if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
                 break;
@@ -2315,6 +2320,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 )
+                goto out;
 
             gmfn = req.ptr >> PAGE_SHIFT;
             mfn = gmfn_to_mfn(d, gmfn);
@@ -2406,6 +2415,10 @@ int do_mmu_update(
             mfn = req.ptr >> PAGE_SHIFT;
             gpfn = req.val;
 
+            rc = xsm_mmu_machphys_update(current->domain, mfn);
+            if ( rc )
+                goto out;
+
             if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) )
             {
                 MEM_LOG("Could not get page for mach->phys update");
@@ -2742,6 +2755,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.l1);
+    if ( rc )
+        return rc;
+
     LOCK_BIGLOCK(d);
 
     pl1e = guest_map_l1e(v, va, &gl1mfn);
@@ -3003,6 +3020,13 @@ 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) )
+        {
+            if (xatp.domid != DOMID_SELF)
+                rcu_unlock_domain(d);
+            return -EPERM;
+        }
+
         switch ( xatp.space )
         {
         case XENMAPSPACE_shared_info:
@@ -3079,6 +3103,14 @@ 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(current->domain, d);
+        if ( rc )
+        {
+            if (fmap.domid != DOMID_SELF)
+                rcu_unlock_domain(d);
+            return rc;
+        }
+
         rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer,
                              fmap.map.nr_entries) ? -EFAULT : 0;
         d->arch.nr_e820 = fmap.map.nr_entries;
@@ -3112,9 +3144,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 e370c94bd6fd -r 62b752969edf xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/physdev.c	Mon May 07 14:50:16 2007 -0400
@@ -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;
@@ -36,6 +37,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EFAULT;
         if ( copy_from_guest(&eoi, arg, 1) != 0 )
             break;
+        ret = xsm_pirq_unmask(current->domain, eoi.irq);
+        if ( ret )
+            break;
         ret = pirq_guest_eoi(current->domain, eoi.irq);
         break;
     }
@@ -55,6 +59,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EINVAL;
         if ( (irq < 0) || (irq >= NR_IRQS) )
             break;
+        ret = xsm_pirq_status(current->domain, irq);
+        if ( ret )
+            break;    
         irq_status_query.flags = 0;
         if ( pirq_acktype(irq) != 0 )
             irq_status_query.flags |= XENIRQSTAT_needs_eoi;
@@ -72,6 +79,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
+        ret = xsm_apic(current->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;
@@ -85,6 +95,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
             break;
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
+            break;
+        ret = xsm_apic(current->domain, cmd);
+        if ( ret )
             break;
         ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
         break;
@@ -101,8 +114,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         if ( !IS_PRIV(current->domain) )
             break;
 
+        ret = xsm_assign_vector(current->domain, irq_op.irq);
+        if ( ret )
+            break;
+        ret = -EINVAL;
+
         irq = irq_op.irq;
-        ret = -EINVAL;
         if ( (irq < 0) || (irq >= NR_IRQS) )
             break;
 
diff -r e370c94bd6fd -r 62b752969edf xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/platform_hypercall.c	Mon May 07 14:50:16 2007 -0400
@@ -22,6 +22,7 @@
 #include <public/platform.h>
 #include <asm/mtrr.h>
 #include "cpu/mtrr/mtrr.h"
+#include <xsm/xsm.h>
 
 #ifndef COMPAT
 typedef long ret_t;
@@ -50,6 +51,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);
@@ -59,6 +64,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,
@@ -77,6 +86,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)
@@ -96,6 +109,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
         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 )
         {
@@ -111,6 +128,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);
@@ -127,6 +149,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 e370c94bd6fd -r 62b752969edf xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/setup.c	Mon May 07 14:50:16 2007 -0400
@@ -33,6 +33,7 @@
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
 #include <xen/kexec.h>
+#include <xsm/xsm.h>
 
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(void);
@@ -655,6 +656,8 @@ void __init __start_xen(multiboot_info_t
 
     percpu_init_areas();
 
+    xsm_init(&initrdidx, mbi, initial_images_start);
+
     init_idle_domain();
 
     trap_init();
diff -r e370c94bd6fd -r 62b752969edf xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/sysctl.c	Mon May 07 14:50:16 2007 -0400
@@ -23,6 +23,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
+#include <xsm/xsm.h>
 
 long arch_do_sysctl(
     struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
@@ -35,6 +36,10 @@ long arch_do_sysctl(
     case XEN_SYSCTL_physinfo:
     {
         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 e370c94bd6fd -r 62b752969edf xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S	Mon May 07 14:50:16 2007 -0400
@@ -673,6 +673,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
@@ -716,6 +717,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 e370c94bd6fd -r 62b752969edf xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/x86_32/mm.c	Mon May 07 14:50:16 2007 -0400
@@ -199,6 +199,7 @@ long subarch_memory_op(int op, XEN_GUEST
     switch ( op )
     {
     case XENMEM_machphys_mfn_list:
+    
         if ( copy_from_guest(&xmml, arg, 1) )
             return -EFAULT;
 
diff -r e370c94bd6fd -r 62b752969edf xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/x86_32/xen.lds.S	Mon May 07 14:50:16 2007 -0400
@@ -63,6 +63,7 @@ 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 e370c94bd6fd -r 62b752969edf xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Sat May 05 13:48:05 2007 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Mon May 07 14:50:16 2007 -0400
@@ -609,6 +609,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
@@ -652,6 +653,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 e370c94bd6fd -r 62b752969edf xen/common/domain.c
--- a/xen/common/domain.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/domain.c	Mon May 07 14:50:16 2007 -0400
@@ -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);
@@ -56,7 +57,15 @@ struct domain *alloc_domain(domid_t domi
         return NULL;
 
     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);
@@ -82,6 +91,7 @@ void free_domain(struct domain *d)
     }
 
     sched_destroy_domain(d);
+    xsm_free_security_domain(d);
     xfree(d);
 }
 
@@ -204,6 +214,9 @@ struct domain *domain_create(
 
     if ( !is_idle_domain(d) )
     {
+        if ( xsm_domain_create(d, ssidref) != 0 )
+            goto fail1;
+
         d->is_paused_by_controller = 1;
         atomic_inc(&d->pause_count);
 
diff -r e370c94bd6fd -r 62b752969edf xen/common/domctl.c
--- a/xen/common/domctl.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/domctl.c	Mon May 07 14:50:16 2007 -0400
@@ -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);
@@ -126,6 +127,8 @@ 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;
@@ -203,6 +206,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = xsm_setvcpucontext(d);
+        if ( ret )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
+
         ret = -EINVAL;
         if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
             goto svc_out;
@@ -250,12 +260,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);
         }
     }
@@ -269,7 +284,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = xsm_unpausedomain(d);
+        if ( ret ) 
+            goto unpausedomain_out;
+
         domain_unpause_by_systemcontroller(d);
+
+    unpausedomain_out:
         rcu_unlock_domain(d);
         ret = 0;
     }
@@ -282,6 +303,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);
@@ -340,6 +368,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
                sizeof(xen_domain_handle_t));
 
         op->domain = d->domain_id;
+
         if ( copy_to_guest(u_domctl, op, 1) )
             ret = -EFAULT;
     }
@@ -357,6 +386,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         ret = -ESRCH;
         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);
@@ -394,12 +430,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);
         }
     }
@@ -417,6 +459,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;
@@ -451,10 +497,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;
@@ -483,12 +534,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;
@@ -502,6 +558,14 @@ 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 )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
 
         ret = -EINVAL;
         if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
@@ -559,6 +623,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;
@@ -594,6 +662,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);
 
@@ -608,6 +680,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         }
         spin_unlock(&d->page_alloc_lock);
 
+    max_mem_out:
         rcu_unlock_domain(d);
     }
     break;
@@ -620,6 +693,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));
@@ -636,6 +716,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;
@@ -659,11 +746,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;
@@ -682,12 +774,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;
@@ -700,6 +797,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 e370c94bd6fd -r 62b752969edf xen/common/event_channel.c
--- a/xen/common/event_channel.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/event_channel.c	Mon May 07 14:50:16 2007 -0400
@@ -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])
@@ -89,8 +90,15 @@ static int get_free_port(struct domain *
     chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET);
     if ( unlikely(chn == NULL) )
         return -ENOMEM;
+    
     memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn));
     bucket_from_port(d, port) = chn;
+
+    if ( xsm_alloc_security_evtchn(chn) )
+    {
+        xfree(chn);
+        return -ENOMEM;
+    }
 
     return port;
 }
@@ -120,6 +128,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 )
@@ -176,6 +188,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;
@@ -231,6 +247,7 @@ static long evtchn_bind_virq(evtchn_bind
         ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
+
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
@@ -261,14 +278,15 @@ static long evtchn_bind_ipi(evtchn_bind_
         ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
+
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
 
     bind->port = port;
 
+    spin_unlock(&d->evtchn_lock);
+
  out:
-    spin_unlock(&d->evtchn_lock);
-
     return rc;
 }
 
@@ -427,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 )
     {
@@ -470,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 )
     {
@@ -500,6 +524,7 @@ long evtchn_send(unsigned int lport)
         ret = -EINVAL;
     }
 
+out:
     spin_unlock(&ld->evtchn_lock);
 
     return ret;
@@ -618,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:
@@ -714,6 +744,8 @@ static long evtchn_unmask(evtchn_unmask_
     shared_info_t *s = d->shared_info;
     int            port = unmask->port;
     struct vcpu   *v;
+    int ret = 0;
+    struct evtchn *chn;
 
     spin_lock(&d->evtchn_lock);
 
@@ -723,7 +755,8 @@ static long evtchn_unmask(evtchn_unmask_
         return -EINVAL;
     }
 
-    v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id];
+    chn = evtchn_from_port(d, port);
+    v = d->vcpu[chn->notify_vcpu_id];
 
     /*
      * These operations must happen in strict order. Based on
@@ -739,7 +772,7 @@ static long evtchn_unmask(evtchn_unmask_
 
     spin_unlock(&d->evtchn_lock);
 
-    return 0;
+    return ret;
 }
 
 
@@ -748,6 +781,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;
@@ -757,6 +791,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);
 
@@ -948,10 +989,14 @@ void notify_via_xen_event_channel(int lp
 
 int evtchn_init(struct domain *d)
 {
+    struct evtchn *chn;
+
     spin_lock_init(&d->evtchn_lock);
     if ( get_free_port(d) != 0 )
         return -EINVAL;
-    evtchn_from_port(d, 0)->state = ECS_RESERVED;
+    chn = evtchn_from_port(d, 0);
+    chn->state = ECS_RESERVED;
+
     return 0;
 }
 
@@ -967,7 +1012,10 @@ void evtchn_destroy(struct domain *d)
     }
 
     for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
+    {
+        xsm_free_security_evtchn(d->evtchn[i]);
         xfree(d->evtchn[i]);
+    }
 }
 
 /*
diff -r e370c94bd6fd -r 62b752969edf xen/common/grant_table.c
--- a/xen/common/grant_table.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/grant_table.c	Mon May 07 14:50:16 2007 -0400
@@ -34,6 +34,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;
@@ -215,6 +216,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);
@@ -439,6 +448,14 @@ __gnttab_unmap_grant_ref(
         /* 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;
     }
 
@@ -644,6 +661,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)) &&
@@ -684,6 +708,7 @@ gnttab_query_size(
     struct gnttab_query_size op;
     struct domain *d;
     domid_t        dom;
+    int rc;
 
     if ( count != 1 )
         return -EINVAL;
@@ -709,6 +734,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;
     }
 
@@ -855,6 +888,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;
         }
 
@@ -1077,6 +1117,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 e370c94bd6fd -r 62b752969edf xen/common/kexec.c
--- a/xen/common/kexec.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/kexec.c	Mon May 07 14:50:16 2007 -0400
@@ -20,6 +20,7 @@
 #include <xen/spinlock.h>
 #include <xen/version.h>
 #include <public/elfnote.h>
+#include <xsm/xsm.h>
 
 #ifndef COMPAT
 
@@ -360,6 +361,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 e370c94bd6fd -r 62b752969edf xen/common/memory.c
--- a/xen/common/memory.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/memory.c	Mon May 07 14:50:16 2007 -0400
@@ -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 e370c94bd6fd -r 62b752969edf xen/common/schedule.c
--- a/xen/common/schedule.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/schedule.c	Mon May 07 14:50:16 2007 -0400
@@ -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 e370c94bd6fd -r 62b752969edf xen/common/sysctl.c
--- a/xen/common/sysctl.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/sysctl.c	Mon May 07 14:50:16 2007 -0400
@@ -21,6 +21,7 @@
 #include <xen/keyhandler.h>
 #include <asm/current.h>
 #include <public/sysctl.h>
+#include <xsm/xsm.h>
 
 extern long arch_do_sysctl(
     struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
@@ -46,6 +47,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,
@@ -57,6 +62,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;
@@ -65,6 +74,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;
@@ -88,6 +101,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,
@@ -96,7 +113,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
                 ret = -EFAULT;
                 break;
             }
-            
+
             num_domains++;
         }
         
@@ -115,6 +132,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 e370c94bd6fd -r 62b752969edf xen/common/xenoprof.c
--- a/xen/common/xenoprof.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/common/xenoprof.c	Mon May 07 14:50:16 2007 -0400
@@ -14,6 +14,7 @@
 #include <xen/sched.h>
 #include <public/xenoprof.h>
 #include <asm/shadow.h>
+#include <xsm/xsm.h>
 
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
@@ -577,6 +578,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 e370c94bd6fd -r 62b752969edf xen/drivers/char/console.c
--- a/xen/drivers/char/console.c	Sat May 05 13:48:05 2007 +0100
+++ b/xen/drivers/char/console.c	Mon May 07 14:50:16 2007 -0400
@@ -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;
@@ -360,6 +361,10 @@ long do_console_io(int cmd, int count, X
         return -EPERM;
 #endif
 
+    rc = xsm_console_io(current->domain, cmd);
+    if (rc)
+        return rc;
+    
     switch ( cmd )
     {
     case CONSOLEIO_write:
diff -r e370c94bd6fd -r 62b752969edf xen/include/public/xen.h
--- a/xen/include/public/xen.h	Sat May 05 13:48:05 2007 +0100
+++ b/xen/include/public/xen.h	Mon May 07 14:50:16 2007 -0400
@@ -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 e370c94bd6fd -r 62b752969edf xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h	Sat May 05 13:48:05 2007 +0100
+++ b/xen/include/xen/hypercall.h	Mon May 07 14:50:16 2007 -0400
@@ -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,9 @@ compat_memory_op(
 
 #endif
 
+extern long
+do_xsm_op(
+    int cmd, 
+    XEN_GUEST_HANDLE(xsm_op_t) u_xsm_op);
+
 #endif /* __XEN_HYPERCALL_H__ */
diff -r e370c94bd6fd -r 62b752969edf xen/include/xen/sched.h
--- a/xen/include/xen/sched.h	Sat May 05 13:48:05 2007 +0100
+++ b/xen/include/xen/sched.h	Mon May 07 14:50:16 2007 -0400
@@ -63,6 +63,7 @@ struct evtchn
         u16 pirq;      /* state == ECS_PIRQ */
         u16 virq;      /* state == ECS_VIRQ */
     } u;
+    void *ssid;
 };
 
 int  evtchn_init(struct domain *d);
diff -r e370c94bd6fd -r 62b752969edf xen/include/xsm/xsm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h	Mon May 07 14:50:16 2007 -0400
@@ -0,0 +1,544 @@
+/*
+ *  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 (int cmd, 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, unsigned long mfn);
+    int (*update_va_mapping) (struct domain *d, intpte_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) (int cmd, 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) (unsigned long mfn);
+    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 (*pirq_unmask) (struct domain *d, int pirq);
+    int (*pirq_status) (struct domain *d, int pirq);
+    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 *d1, 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, unsigned long mfn)
+{
+    return xsm_call(memory_pin_page(d, mfn));
+}
+
+static inline int xsm_update_va_mapping(struct domain *d, intpte_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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+    return xsm_call(__do_xsm_op(cmd, 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 (unsigned long mfn)
+{
+    return xsm_call(getpageframeinfo(mfn));
+}
+
+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_pirq_unmask (struct domain *d, int pirq)
+{
+    return xsm_call(pirq_unmask(d, pirq));
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+    return xsm_call(pirq_status(d, pirq));
+}
+
+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 *d1, struct domain *d2)
+{
+    return xsm_call(domain_memory_map(d1, d2));
+}
+
+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 e370c94bd6fd -r 62b752969edf xen/xsm/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile	Mon May 07 14:50:16 2007 -0400
@@ -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 e370c94bd6fd -r 62b752969edf xen/xsm/dummy.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c	Mon May 07 14:50:16 2007 -0400
@@ -0,0 +1,500 @@
+/*
+ *  This file contains the Flask hook function implementations 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.
+ */
+ 
+#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, intpte_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, unsigned long mfn)
+{
+    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(int cmd, 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 (unsigned long mfn)
+{
+    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_pirq_unmask (struct domain *d, int pirq)
+{
+    return 0;
+}
+
+static int dummy_pirq_status (struct domain *d, int pirq)
+{
+    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 *d1, struct domain *d2)
+{
+    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, pirq_unmask);
+    set_to_dummy_if_null(ops, pirq_status);
+    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 e370c94bd6fd -r 62b752969edf xen/xsm/xsm_core.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c	Mon May 07 14:50:16 2007 -0400
@@ -0,0 +1,114 @@
+/*
+ *  This file contains the Flask hook function implementations 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.
+ */
+ 
+#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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+    return __do_xsm_op(cmd, op);
+}
+
+
diff -r e370c94bd6fd -r 62b752969edf xen/xsm/xsm_policy.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c	Mon May 07 14:50:16 2007 -0400
@@ -0,0 +1,65 @@
+/*
+ *  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 = __va(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;
+}

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-07 21:41 [Xense-devel][PATCH][1/4] Xen Security Modules: XSM George S. Coker, II
@ 2007-05-07 23:10 ` Chris Wright
  2007-05-08  0:59   ` George S. Coker, II
  2007-05-08  2:54 ` Mark Williamson
  2007-05-09 14:04 ` Derek Murray
  2 siblings, 1 reply; 19+ messages in thread
From: Chris Wright @ 2007-05-07 23:10 UTC (permalink / raw)
  To: George S. Coker, II; +Cc: xen-devel, xense-devel

* George S. Coker, II (gscoker@alpha.ncsc.mil) wrote:
> Updates in this patch set include:
>     - adaptation to new create secure interface for domain_create
>     - cleanup of xsm enable/disable framework through xsm_call macro
>     - ifdef architecture/config specific hooks

Thanks, I looked at that quickly, only comment I had there was it
could be:

struct xsm_ops {
generic ones...
struct xsm_arch_ops arch_ops;
}

To avoid a bunch of ifdefs there.  Some of them looked arch neutral
(like add_to_physmap), but I can see they aren't exactly.

Still be nice to make the do_xsm_op hypercall be more than
direct pass-thru to module.

Other than that, a quick review got me looking at evtchn calls.

> diff -r e370c94bd6fd -r 62b752969edf xen/common/event_channel.c
> --- a/xen/common/event_channel.c	Sat May 05 13:48:05 2007 +0100
> +++ b/xen/common/event_channel.c	Mon May 07 14:50:16 2007 -0400
> @@ -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])
> @@ -89,8 +90,15 @@ static int get_free_port(struct domain *
>      chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET);
>      if ( unlikely(chn == NULL) )
>          return -ENOMEM;
> +    
>      memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn));
>      bucket_from_port(d, port) = chn;
> +
> +    if ( xsm_alloc_security_evtchn(chn) )
> +    {
> +        xfree(chn);
> +        return -ENOMEM;
> +    }

Oops, this is a domain triggerable use-after free bug-in-waiting.
Now the bucket is perceived valid, but the memory isn't.

In fact, this is not the right interface.  You are only allocating the
an opaque security blob per bucket, not per channel.  In effect it's like:

struct evtchn chn[EVTCHNS_PER_BUCKET];
xsm_alloc_security(&chn[0]);

When I believe you want smth effectively like:

struct evtchn chn[EVTCHNS_PER_BUCKET];
for (i=0; i < EVTCHNS_PER_BUCKET; i++)
	xsm_alloc_security(&chn[i]);

>      return port;
>  }
> @@ -120,6 +128,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 )
> @@ -176,6 +188,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;
> @@ -231,6 +247,7 @@ static long evtchn_bind_virq(evtchn_bind
>          ERROR_EXIT(port);
>  
>      chn = evtchn_from_port(d, port);
> +
>      chn->state          = ECS_VIRQ;
>      chn->notify_vcpu_id = vcpu;
>      chn->u.virq         = virq;
> @@ -261,14 +278,15 @@ static long evtchn_bind_ipi(evtchn_bind_
>          ERROR_EXIT(port);
>  
>      chn = evtchn_from_port(d, port);
> +
>      chn->state          = ECS_IPI;
>      chn->notify_vcpu_id = vcpu;
>  
>      bind->port = port;
>  
> +    spin_unlock(&d->evtchn_lock);
> +
>   out:
> -    spin_unlock(&d->evtchn_lock);
> -

This is incorrect, leaves domain locked on error path (yes, ERROR_EXIT
is mean macro abuse!).

>      return rc;
>  }
>  
> @@ -427,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 )
>      {
> @@ -470,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 )
>      {
> @@ -500,6 +524,7 @@ long evtchn_send(unsigned int lport)
>          ret = -EINVAL;
>      }
>  
> +out:
>      spin_unlock(&ld->evtchn_lock);
>  
>      return ret;
> @@ -618,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:
> @@ -714,6 +744,8 @@ static long evtchn_unmask(evtchn_unmask_
>      shared_info_t *s = d->shared_info;
>      int            port = unmask->port;
>      struct vcpu   *v;
> +    int ret = 0;
> +    struct evtchn *chn;
>  
>      spin_lock(&d->evtchn_lock);
>  
> @@ -723,7 +755,8 @@ static long evtchn_unmask(evtchn_unmask_
>          return -EINVAL;
>      }
>  
> -    v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id];
> +    chn = evtchn_from_port(d, port);
> +    v = d->vcpu[chn->notify_vcpu_id];
>  
>      /*
>       * These operations must happen in strict order. Based on
> @@ -739,7 +772,7 @@ static long evtchn_unmask(evtchn_unmask_
>  
>      spin_unlock(&d->evtchn_lock);
>  
> -    return 0;
> +    return ret;
>  }
>  
>  
> @@ -748,6 +781,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;
> @@ -757,6 +791,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);
>  
> @@ -948,10 +989,14 @@ void notify_via_xen_event_channel(int lp
>  
>  int evtchn_init(struct domain *d)
>  {
> +    struct evtchn *chn;
> +
>      spin_lock_init(&d->evtchn_lock);
>      if ( get_free_port(d) != 0 )
>          return -EINVAL;
> -    evtchn_from_port(d, 0)->state = ECS_RESERVED;
> +    chn = evtchn_from_port(d, 0);
> +    chn->state = ECS_RESERVED;
> +
>      return 0;
>  }
>  
> @@ -967,7 +1012,10 @@ void evtchn_destroy(struct domain *d)
>      }
>  
>      for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
> +    {
> +        xsm_free_security_evtchn(d->evtchn[i]);

Yeah, like this.  Got it right on destroy.

>          xfree(d->evtchn[i]);
> +    }
>  }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-07 23:10 ` Chris Wright
@ 2007-05-08  0:59   ` George S. Coker, II
  2007-05-08  1:12     ` George S. Coker, II
  2007-05-08  3:08     ` Chris Wright
  0 siblings, 2 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-08  0:59 UTC (permalink / raw)
  To: Chris Wright; +Cc: xen-devel, George S. Coker, II, xense-devel

> Thanks, I looked at that quickly, only comment I had there was it
> could be:
>
> struct xsm_ops {
> generic ones...
> struct xsm_arch_ops arch_ops;
> }
>
I guess I really don't see how this makes it any better since there
will likely always be a mix of XSM "supported" ops and module specific
ops.  If you are trying to tighten down the interface, any command,
support or specific could be abused.  Please remind me what advantage
you are thinking about here.

> To avoid a bunch of ifdefs there.  Some of them looked arch neutral
> (like add_to_physmap), but I can see they aren't exactly.
>
> Still be nice to make the do_xsm_op hypercall be more than
> direct pass-thru to module.
>
> Other than that, a quick review got me looking at evtchn calls.
>
> > diff -r e370c94bd6fd -r 62b752969edf xen/common/event_channel.c
> > --- a/xen/common/event_channel.c      Sat May 05 13:48:05 2007 +0100
> > +++ b/xen/common/event_channel.c      Mon May 07 14:50:16 2007 -0400
> > @@ -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])
> > @@ -89,8 +90,15 @@ static int get_free_port(struct domain *
> >      chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET);
> >      if ( unlikely(chn == NULL) )
> >          return -ENOMEM;
> > +
> >      memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn));
> >      bucket_from_port(d, port) = chn;
> > +
> > +    if ( xsm_alloc_security_evtchn(chn) )
> > +    {
> > +        xfree(chn);
> > +        return -ENOMEM;
> > +    }
>
> Oops, this is a domain triggerable use-after free bug-in-waiting.
> Now the bucket is perceived valid, but the memory isn't.
>
> In fact, this is not the right interface.  You are only allocating the
> an opaque security blob per bucket, not per channel.  In effect it's like:
>
> struct evtchn chn[EVTCHNS_PER_BUCKET];
> xsm_alloc_security(&chn[0]);
>
> When I believe you want smth effectively like:
>
> struct evtchn chn[EVTCHNS_PER_BUCKET];
> for (i=0; i < EVTCHNS_PER_BUCKET; i++)
>         xsm_alloc_security(&chn[i]);
>
> >      return port;
> >  }

This is a mistake in the framework because the behavior between alloc
and free is inconsistent.  The Flask module does this correctly, but
this is a gotcha for a new module.  I'll fix this and repost tomorrow.

> > @@ -120,6 +128,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 )
> > @@ -176,6 +188,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;
> > @@ -231,6 +247,7 @@ static long evtchn_bind_virq(evtchn_bind
> >          ERROR_EXIT(port);
> >
> >      chn = evtchn_from_port(d, port);
> > +
> >      chn->state          = ECS_VIRQ;
> >      chn->notify_vcpu_id = vcpu;
> >      chn->u.virq         = virq;
> > @@ -261,14 +278,15 @@ static long evtchn_bind_ipi(evtchn_bind_
> >          ERROR_EXIT(port);
> >
> >      chn = evtchn_from_port(d, port);
> > +
> >      chn->state          = ECS_IPI;
> >      chn->notify_vcpu_id = vcpu;
> >
> >      bind->port = port;
> >
> > +    spin_unlock(&d->evtchn_lock);
> > +
> >   out:
> > -    spin_unlock(&d->evtchn_lock);
> > -
>
> This is incorrect, leaves domain locked on error path (yes, ERROR_EXIT
> is mean macro abuse!).
>
Absolutely this is a problem, when did ERROR_EXIT come about?

> >      return rc;
> >  }
> >
> > @@ -427,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 )
> >      {
> > @@ -470,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 )
> >      {
> > @@ -500,6 +524,7 @@ long evtchn_send(unsigned int lport)
> >          ret = -EINVAL;
> >      }
> >
> > +out:
> >      spin_unlock(&ld->evtchn_lock);
> >
> >      return ret;
> > @@ -618,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:
> > @@ -714,6 +744,8 @@ static long evtchn_unmask(evtchn_unmask_
> >      shared_info_t *s = d->shared_info;
> >      int            port = unmask->port;
> >      struct vcpu   *v;
> > +    int ret = 0;
> > +    struct evtchn *chn;
> >
> >      spin_lock(&d->evtchn_lock);
> >
> > @@ -723,7 +755,8 @@ static long evtchn_unmask(evtchn_unmask_
> >          return -EINVAL;
> >      }
> >
> > -    v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id];
> > +    chn = evtchn_from_port(d, port);
> > +    v = d->vcpu[chn->notify_vcpu_id];
> >
> >      /*
> >       * These operations must happen in strict order. Based on
> > @@ -739,7 +772,7 @@ static long evtchn_unmask(evtchn_unmask_
> >
> >      spin_unlock(&d->evtchn_lock);
> >
> > -    return 0;
> > +    return ret;
> >  }
> >
> >
> > @@ -748,6 +781,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;
> > @@ -757,6 +791,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);
> >
> > @@ -948,10 +989,14 @@ void notify_via_xen_event_channel(int lp
> >
> >  int evtchn_init(struct domain *d)
> >  {
> > +    struct evtchn *chn;
> > +
> >      spin_lock_init(&d->evtchn_lock);
> >      if ( get_free_port(d) != 0 )
> >          return -EINVAL;
> > -    evtchn_from_port(d, 0)->state = ECS_RESERVED;
> > +    chn = evtchn_from_port(d, 0);
> > +    chn->state = ECS_RESERVED;
> > +
> >      return 0;
> >  }
> >
> > @@ -967,7 +1012,10 @@ void evtchn_destroy(struct domain *d)
> >      }
> >
> >      for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
> > +    {
> > +        xsm_free_security_evtchn(d->evtchn[i]);
>
> Yeah, like this.  Got it right on destroy.
>
> >          xfree(d->evtchn[i]);
> > +    }
> >  }
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-08  0:59   ` George S. Coker, II
@ 2007-05-08  1:12     ` George S. Coker, II
  2007-05-08  3:08     ` Chris Wright
  1 sibling, 0 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-08  1:12 UTC (permalink / raw)
  To: Chris Wright; +Cc: xen-devel, George S. Coker, II, xense-devel

> > >      chn->state          = ECS_VIRQ;
> > >      chn->notify_vcpu_id = vcpu;
> > >      chn->u.virq         = virq;
> > > @@ -261,14 +278,15 @@ static long evtchn_bind_ipi(evtchn_bind_
> > >          ERROR_EXIT(port);
> > >
> > >      chn = evtchn_from_port(d, port);
> > > +
> > >      chn->state          = ECS_IPI;
> > >      chn->notify_vcpu_id = vcpu;
> > >
> > >      bind->port = port;
> > >
> > > +    spin_unlock(&d->evtchn_lock);
> > > +
> > >   out:
> > > -    spin_unlock(&d->evtchn_lock);
> > > -
> >
> > This is incorrect, leaves domain locked on error path (yes, ERROR_EXIT
> > is mean macro abuse!).
> >
> Absolutely this is a problem, when did ERROR_EXIT come about?
>
The patch was generated incorrectly and contains some old edits.  I
don't even mean to be touching this code region.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-07 21:41 [Xense-devel][PATCH][1/4] Xen Security Modules: XSM George S. Coker, II
  2007-05-07 23:10 ` Chris Wright
@ 2007-05-08  2:54 ` Mark Williamson
  2007-05-08 12:44   ` John McDermott (US Navy Employee)
  2007-05-09 14:04 ` Derek Murray
  2 siblings, 1 reply; 19+ messages in thread
From: Mark Williamson @ 2007-05-08  2:54 UTC (permalink / raw)
  To: xen-devel; +Cc: George S. Coker, II, xense-devel

[-- Attachment #1: Type: text/plain, Size: 1209 bytes --]

Hi George,

I've been working on some automated checking tools for the Xen tree and I'm 
afraid your patches came at a convenient time for you to be a test case - 
sorry :-)

> Updates in this patch set include:
>     - adaptation to new create secure interface for domain_create
>     - cleanup of xsm enable/disable framework through xsm_call macro
>     - ifdef architecture/config specific hooks

Right now I've got a load of coding style nits that you might be interested 
in.  I'm attaching the relevant output of the Xen style checking tool 
(derived from a pre-existing Linux style checker) below; I've given it a look 
through to verify that it appears sane.  It's largely based on my 
interpretation of what the Xen codebase style appears to be, so there may be 
some things you disagree with.

I realise you're still iterating on the design, but I hope this is useful for 
getting ready for the merge.  Please feel free to give feedback if you 
disagree with of the details.

Cheers,
Mark

-- 
Dave: Just a question. What use is a unicyle with no seat?  And no pedals!
Mark: To answer a question with a question: What use is a skateboard?
Dave: Skateboards have wheels.
Mark: My wheel has a wheel!

[-- Attachment #2: xsm-050707-xen-15011-checking --]
[-- Type: text/x-objcsrc, Size: 14202 bytes --]

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:112:
FILE: b/xen/arch/x86/domctl.c:76:
+        ret = xsm_ioport_permission(d, fp, domctl->u.ioport_permission.allow_access);

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:178:
FILE: b/xen/arch/x86/domctl.c:347:
+        

need a space after the (
PATCH: xsm-050707-xen-15011.diff:358:
FILE: b/xen/arch/x86/mm.c:3025:
+            if (xatp.domid != DOMID_SELF)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:358:
FILE: b/xen/arch/x86/mm.c:3025:
+            if (xatp.domid != DOMID_SELF)

need a space after the (
PATCH: xsm-050707-xen-15011.diff:373:
FILE: b/xen/arch/x86/mm.c:3109:
+            if (fmap.domid != DOMID_SELF)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:373:
FILE: b/xen/arch/x86/mm.c:3109:
+            if (fmap.domid != DOMID_SELF)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:387:
FILE: b/xen/arch/x86/mm.c:3148:
+        

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:424:
FILE: b/xen/arch/x86/physdev.c:64:
+            break;    

need a space after the (
PATCH: xsm-050707-xen-15011.diff:523:
FILE: b/xen/arch/x86/platform_hypercall.c:133:
+        if (ret)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:523:
FILE: b/xen/arch/x86/platform_hypercall.c:133:
+        if (ret)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:609:
FILE: b/xen/arch/x86/x86_32/mm.c:202:
+    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:620:
FILE: b/xen/arch/x86/x86_32/xen.lds.S:66:
+   .xsm_initcall.init : { __xsm_initcall_start = .; *(.xsm_initcall.init) __xsm_initcall_end = .; }  

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:620:
FILE: b/xen/arch/x86/x86_32/xen.lds.S:66:
+   .xsm_initcall.init : { __xsm_initcall_start = .; *(.xsm_initcall.init) __xsm_initcall_end = .; }  

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:727:
FILE: b/xen/common/domctl.c:264:
+            if ( ret ) 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:745:
FILE: b/xen/common/domctl.c:288:
+        if ( ret ) 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:841:
FILE: b/xen/common/domctl.c:538:
+        if ( ret ) 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:874:
FILE: b/xen/common/domctl.c:627:
+        if ( ret ) 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:932:
FILE: b/xen/common/domctl.c:750:
+        if ( ret ) 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:934:
FILE: b/xen/common/domctl.c:752:
+        

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:991:
FILE: b/xen/common/event_channel.c:93:
+    

need a space after the (
PATCH: xsm-050707-xen-15011.diff:1290:
FILE: b/xen/common/kexec.c:365:
+    if (ret)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:1290:
FILE: b/xen/common/kexec.c:365:
+    if (ret)

need a space after the (
PATCH: xsm-050707-xen-15011.diff:1336:
FILE: b/xen/common/memory.c:553:
+            if (reservation.domid != DOMID_SELF)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:1336:
FILE: b/xen/common/memory.c:553:
+            if (reservation.domid != DOMID_SELF)

need a space after the (
PATCH: xsm-050707-xen-15011.diff:1352:
FILE: b/xen/common/memory.c:607:
+            if (domid != DOMID_SELF)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:1352:
FILE: b/xen/common/memory.c:607:
+            if (domid != DOMID_SELF)

need a space after the (
PATCH: xsm-050707-xen-15011.diff:1497:
FILE: b/xen/drivers/char/console.c:365:
+    if (rc)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:1497:
FILE: b/xen/drivers/char/console.c:365:
+    if (rc)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1499:
FILE: b/xen/drivers/char/console.c:367:
+    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1531:
FILE: b/xen/include/xen/hypercall.h:131:
+    int cmd, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1601:
FILE: b/xen/include/xsm/xsm.h:52:
+    void (*security_domaininfo) (struct domain *d, 

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1623:
FILE: b/xen/include/xsm/xsm.h:74:
+    int (*iomem_permission) (struct domain *d, unsigned long mfn, uint8_t access);

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1627:
FILE: b/xen/include/xsm/xsm.h:78:
+    int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1640:
FILE: b/xen/include/xsm/xsm.h:91:
+    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1651:
FILE: b/xen/include/xsm/xsm.h:102:
+    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1653:
FILE: b/xen/include/xsm/xsm.h:104:
+    

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1664:
FILE: b/xen/include/xsm/xsm.h:115:
+    int (*ioport_permission) (struct domain *d, uint32_t ioport, uint8_t access);

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1682:
FILE: b/xen/include/xsm/xsm.h:133:
+    int (*platform_quirk) (uint32_t);    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1695:
FILE: b/xen/include/xsm/xsm.h:146:
+static inline void xsm_security_domaininfo (struct domain *d, 

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1796:
FILE: b/xen/include/xsm/xsm.h:247:
+static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, uint8_t access)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1799:
FILE: b/xen/include/xsm/xsm.h:250:
+} 

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1801:
FILE: b/xen/include/xsm/xsm.h:252:
+static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, uint8_t access)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1811:
FILE: b/xen/include/xsm/xsm.h:262:
+static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1843:
FILE: b/xen/include/xsm/xsm.h:294:
+static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1851:
FILE: b/xen/include/xsm/xsm.h:302:
+    return xsm_call(grant_unmapref(d1, d2));        

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1898:
FILE: b/xen/include/xsm/xsm.h:349:
+                                        

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:1905:
FILE: b/xen/include/xsm/xsm.h:356:
+static inline int xsm_memory_stat_reservation (struct domain *d1, 

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1959:
FILE: b/xen/include/xsm/xsm.h:410:
+static inline int xsm_init (unsigned int *initrdidx, const multiboot_info_t *mbi,

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:1972:
FILE: b/xen/include/xsm/xsm.h:423:
+static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2120:
FILE: b/xen/xsm/dummy.c:14:
+ 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2124:
FILE: b/xen/xsm/dummy.c:18:
+static void dummy_security_domaininfo(struct domain *d, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2228:
FILE: b/xen/xsm/dummy.c:122:
+} 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2230:
FILE: b/xen/xsm/dummy.c:124:
+static int dummy_iomem_permission (struct domain *d, unsigned long mfn, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2251:
FILE: b/xen/xsm/dummy.c:145:
+static int dummy_grant_mapref (struct domain *d1, struct domain *d2, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2286:
FILE: b/xen/xsm/dummy.c:180:
+                                        

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:2287:
FILE: b/xen/xsm/dummy.c:181:
+static int dummy_memory_adjust_reservation (struct domain *d1, struct domain *d2)

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2327:
FILE: b/xen/xsm/dummy.c:221:
+static int dummy_evtchn_unbound (struct domain *d, struct evtchn *chn, 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2385:
FILE: b/xen/xsm/dummy.c:279:
+static int dummy_ioport_permission (struct domain *d, uint32_t ioport, 

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2511:
FILE: b/xen/xsm/dummy.c:405:
+        if (!ops->function) {                                    \

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2511:
FILE: b/xen/xsm/dummy.c:405:
+        if (!ops->function) {                                    \

test: +            ops->function = dummy_##function;                    \
:'+        if (!ops->function) {                                    \' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2512:
FILE: b/xen/xsm/dummy.c:406:
+            ops->function = dummy_##function;                    \

line over 80 characters
PATCH: xsm-050707-xen-15011.diff:2513:
FILE: b/xen/xsm/dummy.c:407:
+            dprintk(XENLOG_DEBUG, "Had to override the " #function                \

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2543:
FILE: b/xen/xsm/dummy.c:437:
+    

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2624:
FILE: b/xen/xsm/xsm_core.c:14:
+ 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2634:
FILE: b/xen/xsm/xsm_core.c:24:
+            

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2643:
FILE: b/xen/xsm/xsm_core.c:33:
+    if (!ops)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2643:
FILE: b/xen/xsm/xsm_core.c:33:
+    if (!ops)

test: +        (*call) ();
:'+    while (call < __xsm_initcall_end) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2654:
FILE: b/xen/xsm/xsm_core.c:44:
+        (*call) ();

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2663:
FILE: b/xen/xsm/xsm_core.c:53:
+    

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2666:
FILE: b/xen/xsm/xsm_core.c:56:
+    if (XSM_MAGIC) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2666:
FILE: b/xen/xsm/xsm_core.c:56:
+    if (XSM_MAGIC) {

test: +        ret = xsm_policy_init(initrdidx, mbi, initial_images_start);
:'+    if (XSM_MAGIC) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2667:
FILE: b/xen/xsm/xsm_core.c:57:
+        ret = xsm_policy_init(initrdidx, mbi, initial_images_start);

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2668:
FILE: b/xen/xsm/xsm_core.c:58:
+        if (ret) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2668:
FILE: b/xen/xsm/xsm_core.c:58:
+        if (ret) {

test: +            printk("%s: Error initializing policy.\n", __FUNCTION__);
:'+        if (ret) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2669:
FILE: b/xen/xsm/xsm_core.c:59:
+            printk("%s: Error initializing policy.\n", __FUNCTION__);

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2673:
FILE: b/xen/xsm/xsm_core.c:63:
+    

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2674:
FILE: b/xen/xsm/xsm_core.c:64:
+    if (verify(&dummy_xsm_ops)) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2674:
FILE: b/xen/xsm/xsm_core.c:64:
+    if (verify(&dummy_xsm_ops)) {

test: +        printk("%s could not verify "
:'+    if (verify(&dummy_xsm_ops)) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2675:
FILE: b/xen/xsm/xsm_core.c:65:
+        printk("%s could not verify "

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2688:
FILE: b/xen/xsm/xsm_core.c:78:
+    if (verify(ops)) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2688:
FILE: b/xen/xsm/xsm_core.c:78:
+    if (verify(ops)) {

test: +        printk("%s could not verify "
:'+    if (verify(ops)) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2689:
FILE: b/xen/xsm/xsm_core.c:79:
+        printk("%s could not verify "

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2694:
FILE: b/xen/xsm/xsm_core.c:84:
+    if (xsm_ops != &dummy_xsm_ops)

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2694:
FILE: b/xen/xsm/xsm_core.c:84:
+    if (xsm_ops != &dummy_xsm_ops)

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2705:
FILE: b/xen/xsm/xsm_core.c:95:
+    if (ops != xsm_ops) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2705:
FILE: b/xen/xsm/xsm_core.c:95:
+    if (ops != xsm_ops) {

test: +        printk("%s: trying to unregister "
:'+    if (ops != xsm_ops) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2706:
FILE: b/xen/xsm/xsm_core.c:96:
+        printk("%s: trying to unregister "

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2739:
FILE: b/xen/xsm/xsm_policy.c:11:
+ *  

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2749:
FILE: b/xen/xsm/xsm_policy.c:21:
+ 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2762:
FILE: b/xen/xsm/xsm_policy.c:34:
+    u32 *_policy_start; 

test: +        start = initial_images_start + (mod[i].mod_start-mod[0].mod_start);
:'+    for (i = mbi->mods_count-1; i >= 1; i--) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2770:
FILE: b/xen/xsm/xsm_policy.c:42:
+        start = initial_images_start + (mod[i].mod_start-mod[0].mod_start);

need a space after the (
PATCH: xsm-050707-xen-15011.diff:2778:
FILE: b/xen/xsm/xsm_policy.c:50:
+        if ((xsm_magic_t)(*_policy_start) == XSM_MAGIC) {

need a space before the )
PATCH: xsm-050707-xen-15011.diff:2778:
FILE: b/xen/xsm/xsm_policy.c:50:
+        if ((xsm_magic_t)(*_policy_start) == XSM_MAGIC) {

test: +            policy_buffer = (char *)_policy_start;
:'+        if ((xsm_magic_t)(*_policy_start) == XSM_MAGIC) {' That { should be on the next line
PATCH: xsm-050707-xen-15011.diff:2779:
FILE: b/xen/xsm/xsm_policy.c:51:
+            policy_buffer = (char *)_policy_start;

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2782:
FILE: b/xen/xsm/xsm_policy.c:54:
+            printk("Policy len  0x%lx, start at %p.\n", 

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2784:
FILE: b/xen/xsm/xsm_policy.c:56:
+                   

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2788:
FILE: b/xen/xsm/xsm_policy.c:60:
+        

trailing whitespace
PATCH: xsm-050707-xen-15011.diff:2791:
FILE: b/xen/xsm/xsm_policy.c:63:
+    

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-08  0:59   ` George S. Coker, II
  2007-05-08  1:12     ` George S. Coker, II
@ 2007-05-08  3:08     ` Chris Wright
  1 sibling, 0 replies; 19+ messages in thread
From: Chris Wright @ 2007-05-08  3:08 UTC (permalink / raw)
  To: George S. Coker, II
  Cc: Chris Wright, xen-devel, George S. Coker, II, xense-devel

* George S. Coker, II (george.coker@gmail.com) wrote:
> >Thanks, I looked at that quickly, only comment I had there was it
> >could be:
> >
> >struct xsm_ops {
> >generic ones...
> >struct xsm_arch_ops arch_ops;
> >}
> >
> I guess I really don't see how this makes it any better since there
> will likely always be a mix of XSM "supported" ops and module specific
> ops.  If you are trying to tighten down the interface, any command,
> support or specific could be abused.  Please remind me what advantage
> you are thinking about here.

I think we are talking about 2 different things.  I just mean the code
that is currently #ifdef CONFIG_X86 in xsm_operations structure.  Typical
is to embed arch specific data within the toplevel generic structure.
It offers no benefit in code generation or tightening of the interface,
etc.  It's simply a readability/maintainability thing to avoid:

struct xsm_operations{
generic bits
...
#ifdef CONFIG_X86
...
#endif
#ifdef CONFIG_IA64
...
#endif
#ifdef CONFIG_PPC
...
#endif
}

> >To avoid a bunch of ifdefs there.  Some of them looked arch neutral
> >(like add_to_physmap), but I can see they aren't exactly.
> >
> >Still be nice to make the do_xsm_op hypercall be more than
> >direct pass-thru to module.

I think this is what you were referring to.  The advantage only
comes about if there are things that are common to modules (likely)
and really shines if there are functions that also use common data
structures (unlikely) for type safety and general interface sanity.

> >Other than that, a quick review got me looking at evtchn calls.
> >
> >> diff -r e370c94bd6fd -r 62b752969edf xen/common/event_channel.c
> >> --- a/xen/common/event_channel.c      Sat May 05 13:48:05 2007 +0100
> >> +++ b/xen/common/event_channel.c      Mon May 07 14:50:16 2007 -0400
> >> @@ -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])
> >> @@ -89,8 +90,15 @@ static int get_free_port(struct domain *
> >>      chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET);
> >>      if ( unlikely(chn == NULL) )
> >>          return -ENOMEM;
> >> +
> >>      memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn));
> >>      bucket_from_port(d, port) = chn;
> >> +
> >> +    if ( xsm_alloc_security_evtchn(chn) )
> >> +    {
> >> +        xfree(chn);
> >> +        return -ENOMEM;
> >> +    }
> >
> >Oops, this is a domain triggerable use-after free bug-in-waiting.
> >Now the bucket is perceived valid, but the memory isn't.
> >
> >In fact, this is not the right interface.  You are only allocating the
> >an opaque security blob per bucket, not per channel.  In effect it's like:
> >
> >struct evtchn chn[EVTCHNS_PER_BUCKET];
> >xsm_alloc_security(&chn[0]);
> >
> >When I believe you want smth effectively like:
> >
> >struct evtchn chn[EVTCHNS_PER_BUCKET];
> >for (i=0; i < EVTCHNS_PER_BUCKET; i++)
> >        xsm_alloc_security(&chn[i]);
> >
> >>      return port;
> >>  }
> 
> This is a mistake in the framework because the behavior between alloc
> and free is inconsistent.  The Flask module does this correctly, but
> this is a gotcha for a new module.  I'll fix this and repost tomorrow.

Actually Flask got it wrong as well (you probably saw that email later).
I agree, the framework is inconsistent, and I think it makes most sense
to have the alloc/free operate on a single channel.  You may need
to introduce a simple helper that does the loop and handles the error
condition in the framework which is fine.

> >> @@ -120,6 +128,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 )
> >> @@ -176,6 +188,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;
> >> @@ -231,6 +247,7 @@ static long evtchn_bind_virq(evtchn_bind
> >>          ERROR_EXIT(port);
> >>
> >>      chn = evtchn_from_port(d, port);
> >> +
> >>      chn->state          = ECS_VIRQ;
> >>      chn->notify_vcpu_id = vcpu;
> >>      chn->u.virq         = virq;
> >> @@ -261,14 +278,15 @@ static long evtchn_bind_ipi(evtchn_bind_
> >>          ERROR_EXIT(port);
> >>
> >>      chn = evtchn_from_port(d, port);
> >> +
> >>      chn->state          = ECS_IPI;
> >>      chn->notify_vcpu_id = vcpu;
> >>
> >>      bind->port = port;
> >>
> >> +    spin_unlock(&d->evtchn_lock);
> >> +
> >>   out:
> >> -    spin_unlock(&d->evtchn_lock);
> >> -
> >
> >This is incorrect, leaves domain locked on error path (yes, ERROR_EXIT
> >is mean macro abuse!).
> >
> Absolutely this is a problem, when did ERROR_EXIT come about?

It's been there a long time.  I think the issue is about your followup.
Given a couple gratuitous newlines, and this one, etc.  it looks like
there's just a small bit of leftover cruft in the diff.

thanks,
-chris

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-08  2:54 ` Mark Williamson
@ 2007-05-08 12:44   ` John McDermott (US Navy Employee)
  2007-05-08 13:12     ` Mark Williamson
  0 siblings, 1 reply; 19+ messages in thread
From: John McDermott (US Navy Employee) @ 2007-05-08 12:44 UTC (permalink / raw)
  To: Mark Williamson; +Cc: xen-devel, xense-devel

Mark,

Does your tool have a pretty-printing capability? It seems like it would 
be more efficient to just reformat the source to comply with whatever 
standards Xen follows. Everyone could apply the tool before building 
patches or submitting code, but still use their own locally preferred 
style while developing.

Sincerely,

John
-- 
What is the formal meaning of the one-line program
#include "/dev/tty"
----
    .~.                 _      _
    /V\                -o)    -o)
   /( )\               /\\    /\\
   ^^^^^              _\_v   _\_v

J. P. McDermott			Building 12
Code 5542			John.McDermott@NRL.Navy.mil
Naval Research Laboratory	Tel:   +1 202.404.8301
Washington, DC 20375, USA	Fax:   +1 202.404.7942	

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-08 12:44   ` John McDermott (US Navy Employee)
@ 2007-05-08 13:12     ` Mark Williamson
  0 siblings, 0 replies; 19+ messages in thread
From: Mark Williamson @ 2007-05-08 13:12 UTC (permalink / raw)
  To: John McDermott (US Navy Employee); +Cc: xen-devel, xense-devel

> Does your tool have a pretty-printing capability? It seems like it would
> be more efficient to just reformat the source to comply with whatever
> standards Xen follows. Everyone could apply the tool before building
> patches or submitting code, but still use their own locally preferred
> style while developing.

It doesn't have this capability at the moment.  It's just a version of the 
Linux patchstylecheckemail.pl that I've modified to understand the different 
coding conventions in Xen.  GNU indent can quite possibly be configured to 
reformat the code as required - I'll look into finding a configuration setup 
that works for this (I'll probably start with the Linux lindent script and 
work from there - we're reasonably close to Linux conventions in many ways).

The style checker does various checks beyond indenting, though, so it'll still 
be worth running it.  I hope to get the it into mainline Xen at some point so 
that folks can just "make stylecheck" or similar before they submit patches.

Thanks for the feedback!

Cheers,
Mark

-- 
Dave: Just a question. What use is a unicyle with no seat?  And no pedals!
Mark: To answer a question with a question: What use is a skateboard?
Dave: Skateboards have wheels.
Mark: My wheel has a wheel!

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-07 21:41 [Xense-devel][PATCH][1/4] Xen Security Modules: XSM George S. Coker, II
  2007-05-07 23:10 ` Chris Wright
  2007-05-08  2:54 ` Mark Williamson
@ 2007-05-09 14:04 ` Derek Murray
  2007-05-09 14:23   ` Keir Fraser
  2007-05-09 17:13   ` George S. Coker, II
  2 siblings, 2 replies; 19+ messages in thread
From: Derek Murray @ 2007-05-09 14:04 UTC (permalink / raw)
  To: George S. Coker, II; +Cc: xen-devel, xense-devel

I'm interested in whether this code could be used to supersede IS_PRIV 
(dom), particularly when doing an mmu_update operation.

As far as I can see, the xsm_mmu_normal_update() hook is called after  
set_foreigndom(). set_foreigndom() will fail if the calling domain is  
not privileged (!IS_PRIV(current->domain)) and the operation  
specifies a different domain as the foreigndom.

For disaggregation of the domain builder, we would like to be able to  
delegate this privilege to a small, trusted domain (domB): it seems  
to me that XSM would be the cleanest way to do this. Would it  
therefore be possible to add a hook in set_foreigndom() on the ! 
IS_PRIV(d) branch, or is there some security consequence that I am  
overlooking?

Regards,

Derek Murray.

On 7 May 2007, at 22:41, George S. Coker, II wrote:

> Updates in this patch set include:
>     - adaptation to new create secure interface for domain_create
>     - cleanup of xsm enable/disable framework through xsm_call macro
>     - ifdef architecture/config specific hooks
>
> Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>
> <xsm-050707-xen-15011.diff>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-09 14:04 ` Derek Murray
@ 2007-05-09 14:23   ` Keir Fraser
  2007-05-09 17:04     ` George S. Coker, II
  2007-05-09 17:13   ` George S. Coker, II
  1 sibling, 1 reply; 19+ messages in thread
From: Keir Fraser @ 2007-05-09 14:23 UTC (permalink / raw)
  To: Derek Murray, George S. Coker, II; +Cc: xen-devel, xense-devel

On 9/5/07 15:04, "Derek Murray" <Derek.Murray@cl.cam.ac.uk> wrote:

> For disaggregation of the domain builder, we would like to be able to
> delegate this privilege to a small, trusted domain (domB): it seems
> to me that XSM would be the cleanest way to do this. Would it
> therefore be possible to add a hook in set_foreigndom() on the !
> IS_PRIV(d) branch, or is there some security consequence that I am
> overlooking?

Better to get rid of the IS_PRIV() altogether? If we're adding these hooks
all over the place we may as well get some benefit from them, even if it
means adding extra ones. Only question then is whether conflating security
constraints required for correct operation of the Xen platform (i.e.,
capabilities of the disaggregated dom0 domains) with the constraints
required for domU's, and trying to express these in the same security policy
module actually makes sense. It might make sense to 'shim in' a static
built-in policy at those hook points as a pre-filter on the
dynamically-loaded policy for ordinary domUs.

 -- Keir

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-09 14:23   ` Keir Fraser
@ 2007-05-09 17:04     ` George S. Coker, II
  2007-05-11 13:32       ` Derek Murray
  0 siblings, 1 reply; 19+ messages in thread
From: George S. Coker, II @ 2007-05-09 17:04 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Derek Murray, xen-devel, xense-devel

On Wed, 2007-05-09 at 15:23 +0100, Keir Fraser wrote:
> On 9/5/07 15:04, "Derek Murray" <Derek.Murray@cl.cam.ac.uk> wrote:
> 
> > For disaggregation of the domain builder, we would like to be able to
> > delegate this privilege to a small, trusted domain (domB): it seems
> > to me that XSM would be the cleanest way to do this. Would it
> > therefore be possible to add a hook in set_foreigndom() on the !
> > IS_PRIV(d) branch, or is there some security consequence that I am
> > overlooking?
> 
> Better to get rid of the IS_PRIV() altogether? If we're adding these hooks
> all over the place we may as well get some benefit from them, even if it
> means adding extra ones. Only question then is whether conflating security
> constraints required for correct operation of the Xen platform (i.e.,
> capabilities of the disaggregated dom0 domains) with the constraints
> required for domU's, and trying to express these in the same security policy
> module actually makes sense. It might make sense to 'shim in' a static
> built-in policy at those hook points as a pre-filter on the
> dynamically-loaded policy for ordinary domUs.
> 

We could easily move the IS_PRIV() checks to the default/dummy modules.
This would ensure that a static security policy is enforced either in
the XSM enabled/disabled cases or in the case of a security module
neglecting not to implement a specific hook.  In all cases, Xen would be
protected by some security policy.  This is how XSM is setup to behave
today, but it is up to the community to commit to making IS_PRIV() the
default XSM module.

Some review of the current hooks is needed to ensure that existing uses
of IS_PRIV() are completely covered.  I believe this is the case for
almost all of the XSM hooks.  In most code paths where there is an
IS_PRIV() call there is an XSM hook immediately following.  mmu_update
is perhaps an exception.  I believe the hook is in the right place to
control the use of mmu_update and probably does not require an extra
hook in set_foreigndom() but there is a side effect from
set_foreigndom() (FOREIGNDOM is set to some value in the absense of
IS_PRIV()) that must be dealt with in the mmu_update hook.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-09 14:04 ` Derek Murray
  2007-05-09 14:23   ` Keir Fraser
@ 2007-05-09 17:13   ` George S. Coker, II
  1 sibling, 0 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-09 17:13 UTC (permalink / raw)
  To: Derek Murray; +Cc: xen-devel, xense-devel

On Wed, 2007-05-09 at 15:04 +0100, Derek Murray wrote:
> I'm interested in whether this code could be used to supersede IS_PRIV 
> (dom), particularly when doing an mmu_update operation.
> 
> As far as I can see, the xsm_mmu_normal_update() hook is called after  
> set_foreigndom(). set_foreigndom() will fail if the calling domain is  
> not privileged (!IS_PRIV(current->domain)) and the operation  
> specifies a different domain as the foreigndom.
> 
> For disaggregation of the domain builder, we would like to be able to  
> delegate this privilege to a small, trusted domain (domB): it seems  
> to me that XSM would be the cleanest way to do this. Would it  
> therefore be possible to add a hook in set_foreigndom() on the ! 
> IS_PRIV(d) branch, or is there some security consequence that I am  
> overlooking?
> 

I believe we have similar goals here.  It should be possible through the
XSM framework and the Flask-XSM module to define a policy that enables a
fine grain usage model such as disaggregation of the domain builder as
well as others.  The benefit to Flask-XSM is the flexibility provided is
completely general as it is derived through definition of a policy not a
specific module.

I realize my posts here may be out of order, but look on in this same
thread at my other posts regarding management of IS_PRIV() under the XSM
default/dummy module.

I encourage you to look at the existing hooks and see if the interfaces
are suitable for your work as well as determine the kinds of policy you
would like to enforce in the hooks.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-09 17:04     ` George S. Coker, II
@ 2007-05-11 13:32       ` Derek Murray
  2007-05-11 15:10         ` George S. Coker, II
  0 siblings, 1 reply; 19+ messages in thread
From: Derek Murray @ 2007-05-11 13:32 UTC (permalink / raw)
  To: George S. Coker, II; +Cc: xen-devel, Keir Fraser, xense-devel

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]


On 9 May 2007, at 18:04, George S. Coker, II wrote:
> Some review of the current hooks is needed to ensure that existing  
> uses
> of IS_PRIV() are completely covered.  I believe this is the case for
> almost all of the XSM hooks.  In most code paths where there is an
> IS_PRIV() call there is an XSM hook immediately following.  mmu_update
> is perhaps an exception.  I believe the hook is in the right place to
> control the use of mmu_update and probably does not require an extra
> hook in set_foreigndom() but there is a side effect from
> set_foreigndom() (FOREIGNDOM is set to some value in the absense of
> IS_PRIV()) that must be dealt with in the mmu_update hook.

I've checked through changeset 15011 with your latest XSM patchset,  
and looked at each instance of IS_PRIV(). I've attached the report  
with this message.


[-- Attachment #2: IS_PRIV_report.txt --]
[-- Type: text/plain, Size: 7959 bytes --]

arch/x86/mm.c:1897:    else if ( !IS_PRIV(d) )
In set_foreigndom. Policy is to allow operation on self, or else on the IO domain, or else by privileged domain. XSM hooks follow this for the individual mmu_update_ops, some of the individual mmuext_ops and in do_update_va_mapping.

arch/x86/mm.c:2831:    if ( unlikely(!IS_PRIV(current->domain)) )
In do_update_va_mapping_otherdomain. Called immediately before call to set_foreigndom. Policy is to allow operation by privileged domain only. XSM hook is in do_update_va_mapping, but no attempt is made to check the domain.

arch/x86/mm.c:3018:        else if ( !IS_PRIV(current->domain) )
In arch_memory_op, XENMEM_add_to_physmap case. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

arch/x86/mm.c:3101:        else if ( !IS_PRIV(current->domain) )
In arch_memory_op, XENMEM_set_memory_map case. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

arch/x86/mm.c:3149:        if ( !IS_PRIV(current->domain) )
In arch_memory_op, XENMEM_machine_memory_map case. Policy is to allow operation by privileged domain only. XSM hook directly follows this check. XSM hook directly follows this check.

arch/x86/hvm/hvm.c:890:    if ( !IS_PRIV(current->domain) )
In hvmop_set_pci_intx_level. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/x86/hvm/hvm.c:937:    if ( !IS_PRIV(current->domain) )
In hvmop_set_isa_irq_level. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/x86/hvm/hvm.c:984:    if ( !IS_PRIV(current->domain) )
In hvmop_set_pci_link_route. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/x86/hvm/hvm.c:1033:        else if ( IS_PRIV(current->domain) )
In do_hvm_op, HVMOP_{set,get}_param cases. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

arch/x86/traps.c:591:        if ( !IS_PRIV(current->domain) )
In emulate_forced_invalid_op. Does not perform access control, but instead clears a bit in the EDX register (corresponding to Memory Type Range Registers.

arch/x86/platform_hypercall.c:39:    if ( !IS_PRIV(current->domain) )
In do_platform_op. Policy is to allow operation by privileged domain only. XSM hooks are placed in the individual platform_ops. 

arch/x86/mm/shadow/multi.c:912:         IS_PRIV(d) &&
In shadow_get_page_from_l1e. Policy is to allow operation on self or else by privileged domain. No associated XSM hook.

arch/x86/physdev.c:80:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_apic_read case. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/x86/physdev.c:97:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_apic_write case. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/x86/physdev.c:114:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_alloc_irq_vector case. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

arch/ia64/vmx/vmx_hypercall.c:50:    if ( !IS_PRIV(current->domain) )
In hvmop_set_isa_irq_level. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/vmx/vmx_hypercall.c:82:    if ( !IS_PRIV(current->domain) )
In hvmop_set_pci_intx_level. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/vmx/vmx_hypercall.c:127:        else if (IS_PRIV(current->domain)) {
In do_hvm_op, HVMOP_{set,get}_param cases. Policy is to allow operation on self or else by privileged domain. *No associated XSM hook.*

arch/ia64/xen/hypercall.c:343:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_apic_read case. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/xen/hypercall.c:357:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_apic_write case. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/xen/hypercall.c:371:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_alloc_irq_vector case. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/xen/hypercall.c:392:        if ( !IS_PRIV(current->domain) )
In do_physdev_op, PHYSDEVOP_free_irq_vector case. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

arch/ia64/xen/mm.c:2075:        else if (!IS_PRIV(current->domain))
In arch_memory_op, XENMEM_add_to_physmap case. Policy is to allow operation on self or else by privileged domain. *No associated XSM hook.*

arch/ia64/xen/dom0_ops.c:35:    if ( !IS_PRIV(current->domain) )
In arch_do_domctl. Policy is to allow operation by privileged domain only. *No associated XSM hook.*

common/memory.c:235:    else if ( !IS_PRIV(current->domain) )
In translate_gpfn_list. Policy is to allow operation on self or else by privileged domain. XSM hook is called for each mfn in the list.

common/memory.c:350:        rc = IS_PRIV(current->domain) ? -EINVAL : -EPERM;
In memory_exchange. Policy is to allow operation on *self only* (privilege is irrelevant). No associated XSM hook.

common/memory.c:545:        else if ( !IS_PRIV(current->domain) ||
In do_memory_op, XENMEM_{{increase,decrease}_reservation,populate_physmap} cases. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/memory.c:599:        else if ( !IS_PRIV(current->domain) )
In do_memory_op, XENMEM_{{current,maximum}_reservation,maximum_gpfn} cases. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/kexec.c:361:    if ( !IS_PRIV(current->domain) )
In do_kexec_op. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

common/grant_table.c:644:    else if ( unlikely(!IS_PRIV(current->domain)) )
In gnttab_setup_table. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/grant_table.c:720:    else if ( unlikely(!IS_PRIV(current->domain)) )
In gnttab_query_size. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/domctl.c:178:    if ( !IS_PRIV(current->domain) )
In do_domctl. Policy is to allow operation by privileged domain only. XSM hooks are placed in the individual domctls.

common/event_channel.c:116:    else if ( !IS_PRIV(current->domain) )
In evtchn_alloc_unbound. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/event_channel.c:624:    else if ( !IS_PRIV(current->domain) )
In evtchn_status. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/event_channel.c:781:    else if ( !IS_PRIV(current->domain) )
In evtchn_reset. Policy is to allow operation on self or else by privileged domain. XSM hook directly follows this check.

common/sysctl.c:35:    if ( !IS_PRIV(current->domain) )
In do_sysctl. Policy is to allow operation by privileged domain only. XSM hooks are placed in the individual sysctls.

common/schedule.c:453:        if ( !IS_PRIV(current->domain) )
In do_sched_op, SCHEDOP_remote_shutdown case. Policy is to allow operation by privileged domain only. XSM hook directly follows this check.

xsm/acm/acm_simple_type_enforcement_hooks.c:709:    if (!IS_PRIV(current->domain)) {
In ste_pre_grant_setup. Policy is to allow operation by privileged domain only. No associated XSM hook.

xsm/acm/acm_ops.c:41:    return (IS_PRIV(d) ? 0 : -EPERM);
In acm_authorize_acm_ops. Policy is to allow operation by privileged domain only. No associated XSM hook.

[-- Attachment #3: Type: text/plain, Size: 2995 bytes --]


The uses of IS_PRIV() boil down to a few categories:

1. Allow privileged domain only.
2. Allow self and privileged domain only.
3. set_foreigndom()
4. Allow self only, but with a different return code (EINVAL instead  
of EPERM) for privileged domain.
5. Make no access control decision; instead use IS_PRIV() to modify a  
register value.

The presence of XSM hooks can also be categorised:

1. IS_PRIV() directly followed by XSM hook.
2. IS_PRIV() at start of do_*_op function, followed by XSM hooks for  
the individual cases.
3. IS_PRIV() at start of list-processing function, followed by XSM  
hook for each item in the list.
4. IS_PRIV() followed by no XSM hook (mostly in IA64 code).

The untidiest cases are where set_foreigndom() is involved. These  
involve do_mmu_update(), do_update_va_otherdomain() and some  
mmuext_ops. In particular, on the do_update_va_otherdomain() path,  
IS_PRIV is checked twice. It would seem to me that the cleanest way  
to do this is to have the permission check first (can domain X access  
MFN Y of domain Z?), then carry out the set_foreigndom() logic.

I am unsure about the location of the xsm_mmu_normal_update() hook.  
What sort of policy do you envisage being enforced here? In  
particular, the hook is based on the current domain and the value  
that is to be written into the page table. In mod_l1_entry(),  
get_page_from_l1e() is called, which ensures that the page belongs to  
FOREIGNDOM, so would it be possible just to place the hook before  
set_foreigndom()? This would have the added benefit of fewer calls to  
the hook, when multiple updates have been batched together.

I am assuming that there are no latent examples of privilege-as-being- 
dom0 in the code, but I haven't confirmed this.

On 9 May 2007, at 18:13, George S. Coker, II wrote:
> I believe we have similar goals here.  It should be possible  
> through the
> XSM framework and the Flask-XSM module to define a policy that  
> enables a
> fine grain usage model such as disaggregation of the domain builder as
> well as others.  The benefit to Flask-XSM is the flexibility  
> provided is
> completely general as it is derived through definition of a policy  
> not a
> specific module.

It sounds to me that Flask-XSM provides the flexibility that would be  
needed for defining a disaggregation policy. I wonder, though,  
whether the Chinese Wall and Simple Type Enforcement ACM modules  
(which, if I understand correctly, are separate Xen Security Modules  
in this framework) would best be written with the IS_PRIV()- 
replacement code separated out into a "shim" policy as Keir suggested  
in this thread. Perhaps these modules should delegate to the dummy  
policy, and, if they pass these hooks, then try the dynamic policy?  
This would ensure that the Xen static privilege code is in a single  
location and would hence be kept consistent.

Thanks for your input on this, and if I can be of any more help,  
please let me know.

Regards,

Derek Murray.

[-- Attachment #4: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-11 13:32       ` Derek Murray
@ 2007-05-11 15:10         ` George S. Coker, II
  2007-05-11 16:51           ` Keir Fraser
  2007-05-18  3:56           ` Stefan Berger
  0 siblings, 2 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-11 15:10 UTC (permalink / raw)
  To: Derek Murray; +Cc: xen-devel, Keir Fraser, xense-devel

On Fri, 2007-05-11 at 14:32 +0100, Derek Murray wrote:
> On 9 May 2007, at 18:04, George S. Coker, II wrote:
> > Some review of the current hooks is needed to ensure that existing  
> > uses
> > of IS_PRIV() are completely covered.  I believe this is the case for
> > almost all of the XSM hooks.  In most code paths where there is an
> > IS_PRIV() call there is an XSM hook immediately following.  mmu_update
> > is perhaps an exception.  I believe the hook is in the right place to
> > control the use of mmu_update and probably does not require an extra
> > hook in set_foreigndom() but there is a side effect from
> > set_foreigndom() (FOREIGNDOM is set to some value in the absense of
> > IS_PRIV()) that must be dealt with in the mmu_update hook.
> 
> I've checked through changeset 15011 with your latest XSM patchset,  
> and looked at each instance of IS_PRIV(). I've attached the report  
> with this message.
> 
> 
> The uses of IS_PRIV() boil down to a few categories:
> 
> 1. Allow privileged domain only.
> 2. Allow self and privileged domain only.
> 3. set_foreigndom()
> 4. Allow self only, but with a different return code (EINVAL instead  
> of EPERM) for privileged domain.
> 5. Make no access control decision; instead use IS_PRIV() to modify a  
> register value.
> 
> The presence of XSM hooks can also be categorised:
> 
> 1. IS_PRIV() directly followed by XSM hook.
> 2. IS_PRIV() at start of do_*_op function, followed by XSM hooks for  
> the individual cases.
> 3. IS_PRIV() at start of list-processing function, followed by XSM  
> hook for each item in the list.
> 4. IS_PRIV() followed by no XSM hook (mostly in IA64 code).

We're not there yet for IA64, but we will be....any testers out there?
So I think XSM is "there" for all of the IS_PRIV uses, with the
exception of set_foreigndom() and modification of a register value in
traps.c.  (I honestly haven't spent any time thinking about the XSM
equivalent to the use of IS_PRIV in traps.c)

> The untidiest cases are where set_foreigndom() is involved. These  
> involve do_mmu_update(), do_update_va_otherdomain() and some  
> mmuext_ops. In particular, on the do_update_va_otherdomain() path,  
> IS_PRIV is checked twice. It would seem to me that the cleanest way  
> to do this is to have the permission check first (can domain X access  
> MFN Y of domain Z?), then carry out the set_foreigndom() logic.
> 

I think I agree.

> I am unsure about the location of the xsm_mmu_normal_update() hook.  
> What sort of policy do you envisage being enforced here? In  
> particular, the hook is based on the current domain and the value  
> that is to be written into the page table. In mod_l1_entry(),  
> get_page_from_l1e() is called, which ensures that the page belongs to  
> FOREIGNDOM, so would it be possible just to place the hook before  
> set_foreigndom()? This would have the added benefit of fewer calls to  
> the hook, when multiple updates have been batched together.
> 
> I am assuming that there are no latent examples of privilege-as-being- 
> dom0 in the code, but I haven't confirmed this.

I believe you are correct, although this was not always the case, I think.  

> On 9 May 2007, at 18:13, George S. Coker, II wrote:
> > I believe we have similar goals here.  It should be possible  
> > through the
> > XSM framework and the Flask-XSM module to define a policy that  
> > enables a
> > fine grain usage model such as disaggregation of the domain builder as
> > well as others.  The benefit to Flask-XSM is the flexibility  
> > provided is
> > completely general as it is derived through definition of a policy  
> > not a
> > specific module.
> 
> It sounds to me that Flask-XSM provides the flexibility that would be  
> needed for defining a disaggregation policy. I wonder, though,  
> whether the Chinese Wall and Simple Type Enforcement ACM modules  
> (which, if I understand correctly, are separate Xen Security Modules  
> in this framework) would best be written with the IS_PRIV()- 
> replacement code separated out into a "shim" policy as Keir suggested  
> in this thread. Perhaps these modules should delegate to the dummy  
> policy, and, if they pass these hooks, then try the dynamic policy?  
> This would ensure that the Xen static privilege code is in a single  
> location and would hence be kept consistent.
> 
Currently the existing ACM module is implemented as a single XSM module
which stacks (internally) the Chinese Wall and Simple Type Enforcement
functionality.  (This is the preferred approach for stacking.)  ACM-XSM
is one module with the flexibility to enforce STE and/or CW policy.

The existing ACM was designed to be complementary to Xen's IS_PRIV().
Moving IS_PRIV() to the default/dummy XSM module does not alter this
relationship as the hooks used by ACM are orthogonal to the IS_PRIV()
hooks.  On init of the XSM (because ACM-XSM does not define replacements
for these IS_PRIV() hooks), the hooks from the dummy/default module are
integrated (or "shimmed") in to the ACM-XSM module.  So I think XSM can
do what you and Keir are suggesting.

> Thanks for your input on this, and if I can be of any more help,  
> please let me know.
> 
> Regards,
> 
> Derek Murray.
-- 
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-11 15:10         ` George S. Coker, II
@ 2007-05-11 16:51           ` Keir Fraser
  2007-05-11 17:19             ` George S. Coker, II
  2007-05-18  3:56           ` Stefan Berger
  1 sibling, 1 reply; 19+ messages in thread
From: Keir Fraser @ 2007-05-11 16:51 UTC (permalink / raw)
  To: George S. Coker, II, Derek Murray; +Cc: xen-devel, Keir Fraser, xense-devel




On 11/5/07 16:10, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:

>> The untidiest cases are where set_foreigndom() is involved. These
>> involve do_mmu_update(), do_update_va_otherdomain() and some
>> mmuext_ops. In particular, on the do_update_va_otherdomain() path,
>> IS_PRIV is checked twice. It would seem to me that the cleanest way
>> to do this is to have the permission check first (can domain X access
>> MFN Y of domain Z?), then carry out the set_foreigndom() logic.
>> 
> 
> I think I agree.

In this case you theoretically race reuse of the domid, don't you? Actually
you are saved by the RCU mechanism, but why is doing the check after
set_foreigndom() hard? The error path out of e.g., do_mmu_update() will
correctly give up the foreign reference.

 -- Keir

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-11 16:51           ` Keir Fraser
@ 2007-05-11 17:19             ` George S. Coker, II
  0 siblings, 0 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-11 17:19 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Derek Murray, xen-devel, xense-devel

On Fri, 2007-05-11 at 17:51 +0100, Keir Fraser wrote:
> 
> 
> On 11/5/07 16:10, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> 
> >> The untidiest cases are where set_foreigndom() is involved. These
> >> involve do_mmu_update(), do_update_va_otherdomain() and some
> >> mmuext_ops. In particular, on the do_update_va_otherdomain() path,
> >> IS_PRIV is checked twice. It would seem to me that the cleanest way
> >> to do this is to have the permission check first (can domain X access
> >> MFN Y of domain Z?), then carry out the set_foreigndom() logic.
> >> 
> > 
> > I think I agree.
> 
> In this case you theoretically race reuse of the domid, don't you? Actually
> you are saved by the RCU mechanism, but why is doing the check after
> set_foreigndom() hard? The error path out of e.g., do_mmu_update() will
> correctly give up the foreign reference.
> 
I guess it's not, my only concern was for the cleanup of set_foreigndom
which is cleaned up as you point out on the error path.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-11 15:10         ` George S. Coker, II
  2007-05-11 16:51           ` Keir Fraser
@ 2007-05-18  3:56           ` Stefan Berger
  2007-05-18 20:00             ` George S. Coker, II
  1 sibling, 1 reply; 19+ messages in thread
From: Stefan Berger @ 2007-05-18  3:56 UTC (permalink / raw)
  To: George S. Coker, II
  Cc: Derek Murray, xen-devel, Keir Fraser, xense-devel,
	xen-devel-bounces


[-- Attachment #1.1: Type: text/plain, Size: 1612 bytes --]

xen-devel-bounces@lists.xensource.com wrote on 05/11/2007 11:10:08 AM:

> On Fri, 2007-05-11 at 14:32 +0100, Derek Murray wrote:
> > On 9 May 2007, at 18:04, George S. Coker, II wrote:
[...]
> Currently the existing ACM module is implemented as a single XSM module
> which stacks (internally) the Chinese Wall and Simple Type Enforcement
> functionality.  (This is the preferred approach for stacking.)  ACM-XSM
> is one module with the flexibility to enforce STE and/or CW policy.
> 
> The existing ACM was designed to be complementary to Xen's IS_PRIV().
> Moving IS_PRIV() to the default/dummy XSM module does not alter this
> relationship as the hooks used by ACM are orthogonal to the IS_PRIV()
> hooks.  On init of the XSM (because ACM-XSM does not define replacements
> for these IS_PRIV() hooks), the hooks from the dummy/default module are
> integrated (or "shimmed") in to the ACM-XSM module.  So I think XSM can

If ACM-XSM does not define replacements for the IS_PRIV() hooks, how are 
you going to integrate them into ACM-XSM? If so, based on what information 
from the current ACM policy would ACM-XSM enforce the IS_PRIV() check? 
What if ACM is not active, what enforces IS_PRIV() then?

   Stefan

> do what you and Keir are suggesting.


> 
> > Thanks for your input on this, and if I can be of any more help, 
> > please let me know.
> > 
> > Regards,
> > 
> > Derek Murray.
> -- 
> George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

[-- Attachment #1.2: Type: text/html, Size: 2075 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
  2007-05-18  3:56           ` Stefan Berger
@ 2007-05-18 20:00             ` George S. Coker, II
  0 siblings, 0 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-05-18 20:00 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Derek Murray, xen-devel, Keir Fraser, xense-devel,
	xen-devel-bounces

On Thu, 2007-05-17 at 23:56 -0400, Stefan Berger wrote:
> 
> xen-devel-bounces@lists.xensource.com wrote on 05/11/2007 11:10:08 AM:
> 
> > On Fri, 2007-05-11 at 14:32 +0100, Derek Murray wrote:
> > > On 9 May 2007, at 18:04, George S. Coker, II wrote:
> [...]
> > Currently the existing ACM module is implemented as a single XSM
> module
> > which stacks (internally) the Chinese Wall and Simple Type
> Enforcement
> > functionality.  (This is the preferred approach for stacking.)
>  ACM-XSM
> > is one module with the flexibility to enforce STE and/or CW policy.
> > 
> > The existing ACM was designed to be complementary to Xen's
> IS_PRIV().
> > Moving IS_PRIV() to the default/dummy XSM module does not alter this
> > relationship as the hooks used by ACM are orthogonal to the
> IS_PRIV()
> > hooks.  On init of the XSM (because ACM-XSM does not define
> replacements
> > for these IS_PRIV() hooks), the hooks from the dummy/default module
> are
> > integrated (or "shimmed") in to the ACM-XSM module.  So I think XSM
> can 
> 
> If ACM-XSM does not define replacements for the IS_PRIV() hooks, how
> are you going to integrate them into ACM-XSM? If so, based on what
> information from the current ACM policy would ACM-XSM enforce the
> IS_PRIV() check? What if ACM is not active, what enforces IS_PRIV()
> then? 
> 

I think I am being misunderstood here.  In this discussion, I have
suggested that we could move the management of the IS_PRIV() checks
under XSM.  If this were to happen, these checks would be managed as the
default behavior of the XSM dummy module as well as be the default
behavior of XSM when disabled.  If XSM is not enabled, Xen will still
behave as expected.

On initialization, XSM does a check of a module's defined hooks, if a
module does not define a hook, the equivalent hook from the dummy module
is registered.  With the exception of the domain_create hook, the hooks
used by ACM-XSM are orthogonal to IS_PRIV().  For domain_create, the
corresponding ACM-XSM hook would need to add an IS_PRIV() call under
this proposal.  For the other hooks not used by ACM-XSM, the XSM init
process registers the dummy hooks containing the default IS_PRIV()
checks.  This is how XSM works today, except that the default/dummy
hooks currently return "0".

George

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [Xense-devel][PATCH][1/4] Xen Security Modules: XSM
@ 2007-06-04 19:06 George S. Coker, II
  0 siblings, 0 replies; 19+ messages in thread
From: George S. Coker, II @ 2007-06-04 19:06 UTC (permalink / raw)
  To: xen-devel, xense-devel

[-- Attachment #1: Type: text/plain, Size: 612 bytes --]

Updates in this patch set include:
    - coding style cleanups
    - adjustment of interface for xsm_update_va_mapping
      (enables direct use of xen macros for pte/pfn/mfn translations)
    - implement event channel security_alloc/dealloc to operate on a
      single event channel
    - remove patch cruft

TODO:
    - documentation of the hook interfaces

TBD:
    - additional cleanups & management of xsm ops beyond current ifdef
      - performance impact of levels of indirection vs. manageability
    - compile time removal of all xsm indirection

Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>


[-- Attachment #2: xsm-060407-xen-15200.diff --]
[-- Type: text/x-patch, Size: 76422 bytes --]

diff -r bd3d6b4c52ec -r cb2ecf48cf80 Config.mk
--- a/Config.mk	Fri Jun 01 14:50:52 2007 +0100
+++ b/Config.mk	Mon Jun 04 11:06:10 2007 -0400
@@ -72,6 +72,10 @@ 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
diff -r bd3d6b4c52ec -r cb2ecf48cf80 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Fri Jun 01 14:50:52 2007 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Mon Jun 04 11:06:10 2007 -0400
@@ -402,6 +402,12 @@ HYPERVISOR_kexec_op(
 	return _hypercall2(int, kexec_op, op, args);
 }
 
+static inline int
+HYPERVISOR_xsm_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, xsm_op, cmd, arg);
+}
 
 
 #endif /* __HYPERCALL_H__ */
diff -r bd3d6b4c52ec -r cb2ecf48cf80 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Fri Jun 01 14:50:52 2007 +0100
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Mon Jun 04 11:06:10 2007 -0400
@@ -403,4 +403,11 @@ HYPERVISOR_kexec_op(
 	return _hypercall2(int, kexec_op, op, args);
 }
 
+static inline int
+HYPERVISOR_xsm_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, xsm_op, cmd, arg);
+}
+
 #endif /* __HYPERCALL_H__ */
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/Makefile
--- a/xen/Makefile	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/Makefile	Mon Jun 04 11:06:10 2007 -0400
@@ -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
@@ -138,7 +139,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/Rules.mk
--- a/xen/Rules.mk	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/Rules.mk	Mon Jun 04 11:06:10 2007 -0400
@@ -47,10 +47,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/domctl.c	Mon Jun 04 11:06:10 2007 -0400
@@ -25,6 +25,7 @@
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
 #include <public/hvm/e820.h>
+#include <xsm/xsm.h>
 
 long arch_do_domctl(
     struct xen_domctl *domctl,
@@ -42,6 +43,13 @@ long arch_do_domctl(
         d = rcu_lock_domain_by_id(domctl->domain);
         if ( d != NULL )
         {
+            ret = xsm_shadow_control(d, domctl->u.shadow_op.op);
+            if ( ret )
+            {
+                rcu_unlock_domain(d);
+                break;
+            }
+
             ret = paging_domctl(d,
                                 &domctl->u.shadow_op,
                                 guest_handle_cast(u_domctl, void));
@@ -64,6 +72,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;
@@ -88,6 +104,13 @@ long arch_do_domctl(
         if ( unlikely(!mfn_valid(mfn)) ||
              unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
             break;
+
+        ret = xsm_getpageframeinfo(mfn);
+        if ( ret )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
 
         page = mfn_to_page(mfn);
 
@@ -172,6 +195,10 @@ long arch_do_domctl(
                 struct page_info *page;
                 unsigned long mfn = arr32[j];
 
+                ret = xsm_getpageframeinfo(mfn);
+                if ( ret )
+                    continue;
+
                 page = mfn_to_page(mfn);
 
                 if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 
@@ -231,6 +258,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);
@@ -270,6 +304,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;
@@ -305,6 +346,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;
@@ -338,6 +383,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;
@@ -391,6 +440,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
@@ -417,6 +473,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c	Mon Jun 04 11:06:10 2007 -0400
@@ -1,3 +1,4 @@
+
 /*
  * hvm.c: Common hardware virtual machine abstractions.
  *
@@ -913,6 +914,10 @@ static int hvmop_set_pci_intx_level(
     if ( d == NULL )
         return -ESRCH;
 
+    rc = xsm_hvm_set_pci_intx_level(d);
+    if ( rc )
+        goto out;
+
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
         goto out;
@@ -956,6 +961,10 @@ static int hvmop_set_isa_irq_level(
     if ( d == NULL )
         return -ESRCH;
 
+    rc = xsm_hvm_set_isa_irq_level(d);
+    if ( rc )
+        goto out;
+
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
         goto out;
@@ -998,6 +1007,10 @@ static int hvmop_set_pci_link_route(
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
+
+    rc = xsm_hvm_set_pci_link_route(d);
+    if ( rc )
+        goto out;
 
     rc = -EINVAL;
     if ( !is_hvm_domain(d) )
@@ -1041,6 +1054,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
 
         if ( d == NULL )
             return -ESRCH;
+
+        rc = xsm_hvm_param(d, op);
+        if ( rc )
+            goto param_fail;
 
         rc = -EINVAL;
         if ( !is_hvm_domain(d) )
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/irq.c	Mon Jun 04 11:06:10 2007 -0400
@@ -16,6 +16,7 @@
 #include <xen/compat.h>
 #include <asm/current.h>
 #include <asm/smpboot.h>
+#include <xsm/xsm.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
 int opt_noirqbalance = 0;
@@ -333,6 +334,9 @@ int pirq_guest_unmask(struct domain *d)
           irq < NR_IRQS;
           irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
     {
+        if ( xsm_pirq_unmask(d, irq) )
+            continue;
+
         if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) )
             __pirq_guest_eoi(d, irq);
     }
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/mm.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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)
 
@@ -2033,6 +2034,10 @@ int do_mmuext_op(
             type = PGT_l4_page_table;
 
         pin_page:
+            rc = xsm_memory_pin_page(current->domain, mfn);
+            if ( rc )
+                break;
+
             /* Ignore pinning of invalid paging levels. */
             if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
                 break;
@@ -2318,6 +2323,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 )
+                goto out;
 
             gmfn = req.ptr >> PAGE_SHIFT;
             mfn = gmfn_to_mfn(d, gmfn);
@@ -2409,6 +2418,10 @@ int do_mmu_update(
             mfn = req.ptr >> PAGE_SHIFT;
             gpfn = req.val;
 
+            rc = xsm_mmu_machphys_update(current->domain, mfn);
+            if ( rc )
+                goto out;
+
             if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) )
             {
                 MEM_LOG("Could not get page for mach->phys update");
@@ -2786,6 +2799,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);
@@ -3047,6 +3064,13 @@ 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) )
+        {
+            if ( xatp.domid != DOMID_SELF )
+                rcu_unlock_domain(d);
+            return -EPERM;
+        }
+
         switch ( xatp.space )
         {
         case XENMAPSPACE_shared_info:
@@ -3123,6 +3147,14 @@ 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(current->domain, d);
+        if ( rc )
+        {
+            if ( fmap.domid != DOMID_SELF )
+                rcu_unlock_domain(d);
+            return rc;
+        }
+
         rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer,
                              fmap.map.nr_entries) ? -EFAULT : 0;
         d->arch.nr_e820 = fmap.map.nr_entries;
@@ -3156,9 +3188,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/physdev.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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;
@@ -36,6 +37,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EFAULT;
         if ( copy_from_guest(&eoi, arg, 1) != 0 )
             break;
+        ret = xsm_pirq_unmask(current->domain, eoi.irq);
+        if ( ret )
+            break;
         ret = pirq_guest_eoi(current->domain, eoi.irq);
         break;
     }
@@ -55,6 +59,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EINVAL;
         if ( (irq < 0) || (irq >= NR_IRQS) )
             break;
+        ret = xsm_pirq_status(current->domain, irq);
+        if ( ret )
+            break;    
         irq_status_query.flags = 0;
         if ( pirq_acktype(irq) != 0 )
             irq_status_query.flags |= XENIRQSTAT_needs_eoi;
@@ -72,6 +79,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
+        ret = xsm_apic(current->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;
@@ -86,6 +96,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
+        ret = xsm_apic(current->domain, cmd);
+        if ( ret )
+            break;
         ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
         break;
     }
@@ -99,6 +112,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
 
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
+            break;
+
+        ret = xsm_assign_vector(current->domain, irq_op.irq);
+        if ( ret )
             break;
 
         irq = irq_op.irq;
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/platform_hypercall.c	Mon Jun 04 11:06:10 2007 -0400
@@ -22,6 +22,7 @@
 #include <public/platform.h>
 #include <asm/mtrr.h>
 #include "cpu/mtrr/mtrr.h"
+#include <xsm/xsm.h>
 
 #ifndef COMPAT
 typedef long ret_t;
@@ -50,6 +51,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);
@@ -59,6 +64,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,
@@ -77,6 +86,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)
@@ -96,6 +109,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
         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 )
         {
@@ -111,6 +128,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);
@@ -127,6 +149,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/setup.c	Mon Jun 04 11:06:10 2007 -0400
@@ -33,6 +33,7 @@
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
 #include <xen/kexec.h>
+#include <xsm/xsm.h>
 
 #if defined(CONFIG_X86_64)
 #define BOOTSTRAP_DIRECTMAP_END (1UL << 32)
@@ -790,6 +791,8 @@ void __init __start_xen(multiboot_info_t
 
     percpu_init_areas();
 
+    xsm_init(&initrdidx, mbi, initial_images_start);
+
     init_idle_domain();
 
     trap_init();
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/sysctl.c	Mon Jun 04 11:06:10 2007 -0400
@@ -23,6 +23,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
+#include <xsm/xsm.h>
 
 long arch_do_sysctl(
     struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
@@ -35,6 +36,10 @@ long arch_do_sysctl(
     case XEN_SYSCTL_physinfo:
     {
         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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S	Mon Jun 04 11:06:10 2007 -0400
@@ -673,6 +673,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
@@ -716,6 +717,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/x86_32/xen.lds.S	Mon Jun 04 11:06:10 2007 -0400
@@ -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 bd3d6b4c52ec -r cb2ecf48cf80 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Mon Jun 04 11:06:10 2007 -0400
@@ -609,6 +609,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
@@ -652,6 +653,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/domain.c
--- a/xen/common/domain.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/domain.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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);
 }
 
@@ -191,6 +200,9 @@ struct domain *domain_create(
 
     if ( !is_idle_domain(d) )
     {
+        if ( xsm_domain_create(d, ssidref) != 0 )
+            goto fail1;
+
         d->is_paused_by_controller = 1;
         atomic_inc(&d->pause_count);
 
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/common/domctl.c
--- a/xen/common/domctl.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/domctl.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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);
@@ -126,7 +127,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);
@@ -203,6 +206,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = xsm_setvcpucontext(d);
+        if ( ret )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
+
         ret = -EINVAL;
         if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
             goto svc_out;
@@ -250,12 +260,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);
         }
     }
@@ -269,7 +284,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         if ( d == NULL )
             break;
 
+        ret = xsm_unpausedomain(d);
+        if ( ret )
+            goto unpausedomain_out;
+
         domain_unpause_by_systemcontroller(d);
+
+    unpausedomain_out:
         rcu_unlock_domain(d);
         ret = 0;
     }
@@ -282,6 +303,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);
@@ -358,6 +386,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);
 
@@ -394,12 +429,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);
         }
     }
@@ -417,6 +458,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;
@@ -451,10 +496,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;
@@ -483,12 +533,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;
@@ -502,6 +557,13 @@ 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 )
+        {
+            rcu_unlock_domain(d);
+            break;
+        }
 
         ret = -EINVAL;
         if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
@@ -559,6 +621,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;
@@ -594,6 +660,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);
 
@@ -608,6 +678,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         }
         spin_unlock(&d->page_alloc_lock);
 
+    max_mem_out:
         rcu_unlock_domain(d);
     }
     break;
@@ -620,6 +691,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));
@@ -636,6 +714,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;
@@ -659,11 +744,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;
@@ -682,12 +772,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;
@@ -700,6 +795,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/event_channel.c
--- a/xen/common/event_channel.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/event_channel.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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;
 
     for ( port = 0; port_is_valid(d, port); port++ )
         if ( evtchn_from_port(d, port)->state == ECS_FREE )
@@ -92,6 +94,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;
 }
 
@@ -120,6 +135,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 )
@@ -176,6 +195,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;
@@ -427,6 +450,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 )
     {
@@ -470,6 +495,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 )
     {
@@ -500,6 +529,7 @@ long evtchn_send(unsigned int lport)
         ret = -EINVAL;
     }
 
+out:
     spin_unlock(&ld->evtchn_lock);
 
     return ret;
@@ -618,6 +648,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:
@@ -748,6 +783,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;
@@ -756,6 +792,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);
@@ -967,7 +1010,10 @@ void evtchn_destroy(struct domain *d)
     }
 
     for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
+    {
+        xsm_free_security_evtchn(d->evtchn[i]);
         xfree(d->evtchn[i]);
+    }
 }
 
 /*
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/common/grant_table.c
--- a/xen/common/grant_table.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/grant_table.c	Mon Jun 04 11:06:10 2007 -0400
@@ -34,6 +34,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;
@@ -225,6 +226,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);
@@ -449,6 +458,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;
     }
 
@@ -706,6 +723,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)) &&
@@ -746,6 +770,7 @@ gnttab_query_size(
     struct gnttab_query_size op;
     struct domain *d;
     domid_t        dom;
+    int rc;
 
     if ( count != 1 )
         return -EINVAL;
@@ -771,6 +796,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;
     }
 
@@ -917,6 +950,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;
         }
 
@@ -1139,6 +1179,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/kexec.c
--- a/xen/common/kexec.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/kexec.c	Mon Jun 04 11:06:10 2007 -0400
@@ -20,6 +20,7 @@
 #include <xen/spinlock.h>
 #include <xen/version.h>
 #include <public/elfnote.h>
+#include <xsm/xsm.h>
 
 #ifndef COMPAT
 
@@ -360,6 +361,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/memory.c
--- a/xen/common/memory.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/memory.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/schedule.c
--- a/xen/common/schedule.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/schedule.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/sysctl.c
--- a/xen/common/sysctl.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/sysctl.c	Mon Jun 04 11:06:10 2007 -0400
@@ -21,6 +21,7 @@
 #include <xen/keyhandler.h>
 #include <asm/current.h>
 #include <public/sysctl.h>
+#include <xsm/xsm.h>
 
 extern long arch_do_sysctl(
     struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
@@ -46,6 +47,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,
@@ -57,6 +62,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;
@@ -65,6 +74,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;
@@ -87,6 +100,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
                 continue;
             if ( num_domains == op->u.getdomaininfolist.max_domains )
                 break;
+
+            ret = xsm_getdomaininfo(d);
+            if ( ret )
+                continue;
 
             getdomaininfo(d, &info);
 
@@ -115,6 +132,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/common/xenoprof.c	Mon Jun 04 11:06:10 2007 -0400
@@ -14,6 +14,7 @@
 #include <xen/sched.h>
 #include <public/xenoprof.h>
 #include <asm/shadow.h>
+#include <xsm/xsm.h>
 
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
@@ -577,6 +578,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/drivers/char/console.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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;
@@ -359,6 +360,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 bd3d6b4c52ec -r cb2ecf48cf80 xen/include/public/xen.h
--- a/xen/include/public/xen.h	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/include/public/xen.h	Mon Jun 04 11:06:10 2007 -0400
@@ -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 bd3d6b4c52ec -r cb2ecf48cf80 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/include/xen/hypercall.h	Mon Jun 04 11:06:10 2007 -0400
@@ -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,9 @@ compat_memory_op(
 
 #endif
 
+extern long
+do_xsm_op(
+    int cmd,
+    XEN_GUEST_HANDLE(xsm_op_t) u_xsm_op);
+
 #endif /* __XEN_HYPERCALL_H__ */
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h	Fri Jun 01 14:50:52 2007 +0100
+++ b/xen/include/xen/sched.h	Mon Jun 04 11:06:10 2007 -0400
@@ -63,6 +63,7 @@ struct evtchn
         u16 pirq;      /* state == ECS_PIRQ */
         u16 virq;      /* state == ECS_VIRQ */
     } u;
+    void *ssid;
 };
 
 int  evtchn_init(struct domain *d);
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/include/xsm/xsm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h	Mon Jun 04 11:06:10 2007 -0400
@@ -0,0 +1,549 @@
+/*
+ *  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 (int cmd, 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, unsigned long mfn);
+    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) (int cmd, 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) (unsigned long mfn);
+    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 (*pirq_unmask) (struct domain *d, int pirq);
+    int (*pirq_status) (struct domain *d, int pirq);
+    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 *d1, 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, unsigned long mfn)
+{
+    return xsm_call(memory_pin_page(d, mfn));
+}
+
+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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+    return xsm_call(__do_xsm_op(cmd, 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 (unsigned long mfn)
+{
+    return xsm_call(getpageframeinfo(mfn));
+}
+
+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_pirq_unmask (struct domain *d, int pirq)
+{
+    return xsm_call(pirq_unmask(d, pirq));
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+    return xsm_call(pirq_status(d, pirq));
+}
+
+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 *d1, struct domain *d2)
+{
+    return xsm_call(domain_memory_map(d1, d2));
+}
+
+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 bd3d6b4c52ec -r cb2ecf48cf80 xen/xsm/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile	Mon Jun 04 11:06:10 2007 -0400
@@ -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 bd3d6b4c52ec -r cb2ecf48cf80 xen/xsm/dummy.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c	Mon Jun 04 11:06:10 2007 -0400
@@ -0,0 +1,502 @@
+/*
+ *  This file contains the Flask hook function implementations 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.
+ */
+
+#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, unsigned long mfn)
+{
+    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(int cmd, 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 (unsigned long mfn)
+{
+    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_pirq_unmask (struct domain *d, int pirq)
+{
+    return 0;
+}
+
+static int dummy_pirq_status (struct domain *d, int pirq)
+{
+    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 *d1, struct domain *d2)
+{
+    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, pirq_unmask);
+    set_to_dummy_if_null(ops, pirq_status);
+    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 bd3d6b4c52ec -r cb2ecf48cf80 xen/xsm/xsm_core.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c	Mon Jun 04 11:06:10 2007 -0400
@@ -0,0 +1,120 @@
+/*
+ *  This file contains the Flask hook function implementations 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.
+ */
+
+#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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+    return __do_xsm_op(cmd, op);
+}
+
+
diff -r bd3d6b4c52ec -r cb2ecf48cf80 xen/xsm/xsm_policy.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c	Mon Jun 04 11:06:10 2007 -0400
@@ -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 = __va(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;
+}

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2007-06-04 19:06 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-07 21:41 [Xense-devel][PATCH][1/4] Xen Security Modules: XSM George S. Coker, II
2007-05-07 23:10 ` Chris Wright
2007-05-08  0:59   ` George S. Coker, II
2007-05-08  1:12     ` George S. Coker, II
2007-05-08  3:08     ` Chris Wright
2007-05-08  2:54 ` Mark Williamson
2007-05-08 12:44   ` John McDermott (US Navy Employee)
2007-05-08 13:12     ` Mark Williamson
2007-05-09 14:04 ` Derek Murray
2007-05-09 14:23   ` Keir Fraser
2007-05-09 17:04     ` George S. Coker, II
2007-05-11 13:32       ` Derek Murray
2007-05-11 15:10         ` George S. Coker, II
2007-05-11 16:51           ` Keir Fraser
2007-05-11 17:19             ` George S. Coker, II
2007-05-18  3:56           ` Stefan Berger
2007-05-18 20:00             ` George S. Coker, II
2007-05-09 17:13   ` George S. Coker, II
  -- strict thread matches above, loose matches on Subject: below --
2007-06-04 19:06 George S. Coker, II

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.