All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xense-devel][RFC][PATCH][1/4] Xen Security Modules: XSM
@ 2006-09-01 16:58 George S. Coker, II
  2006-09-01 18:35 ` James Morris
  2006-09-01 18:55 ` Chris Wright
  0 siblings, 2 replies; 11+ messages in thread
From: George S. Coker, II @ 2006-09-01 16:58 UTC (permalink / raw)
  To: xen-devel; +Cc: xense-devel

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


The attached patch implements the Xen Security Modules (XSM) framework.
This patch should apply cleanly to changeset 9694:d82a4c4d04d4 Xen
3.0.2-3.

The framework is configured as default-enable in this patch set.
Configuration of XSM is made in Config.mk.  The only configuration
option is XSM_ENABLE = y/n.  XSM_ENABLE must be y to compile an XSM
module.  

XSM provides a generalized hook infrastructure allowing third-party
security modules to interpose on the Xen code path.  A default or dummy
module provides basic call/return functionality for hooks not
implemented by a given module.  During module initialization, a module
registers its security hooks and the equivalent dummy hooks are
unregistered.  If a module does not implement a hook, the equivalent
dummy hook remains in place.  Modules also may define and register at
boot time a module specific hypercall through the XSM hook
infrastructure.

Modules may also define at Xen compile time a magic number XSM_MAGIC to
indicate that a policy should be discovered from the images loaded at
boot.  The policy file should then be listed in grub as one of the
multi-boot modules after the dom0 kernel.


[-- Attachment #2: xsm-xen-3.0.2-3.diff --]
[-- Type: text/x-patch, Size: 65576 bytes --]

diff -r d82a4c4d04d4 -r a24b5a5f5f5b Config.mk
--- a/Config.mk    Fri May 26 09:23:33 2006 +0100
+++ b/Config.mk    Thu Aug 31 17:14:49 2006 -0400
@@ -71,6 +71,10 @@ CFLAGS += $(foreach i, $(EXTRA_INCLUDES)
 # Choose the best mirror to download linux kernel
 KERNEL_REPO = http://www.kernel.org
 
+#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 d82a4c4d04d4 -r a24b5a5f5f5b linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c    Fri May 26 09:23:33 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c    Thu Aug 31 17:14:49 2006 -0400
@@ -264,6 +264,7 @@ static int __init privcmd_init(void)
 {
 	/* Set of hypercalls that privileged applications may execute. */
 	set_bit(__HYPERVISOR_acm_op,           hypercall_permission_map);
+	set_bit(__HYPERVISOR_xsm_op,           hypercall_permission_map);
 	set_bit(__HYPERVISOR_dom0_op,          hypercall_permission_map);
 	set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map);
 	set_bit(__HYPERVISOR_memory_op,        hypercall_permission_map);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/Makefile
--- a/xen/Makefile    Fri May 26 09:23:33 2006 +0100
+++ b/xen/Makefile    Thu Aug 31 17:14:49 2006 -0400
@@ -45,6 +45,7 @@ _clean: delete-unfresh-files
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
+	$(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
 	rm -f include/asm *.o $(TARGET)* *~ core
 	rm -f include/asm-*/asm-offsets.h
@@ -122,7 +123,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
 	  echo ""; \
 	  echo "#endif") <$< >$@
 
-SUBDIRS = acm arch/$(TARGET_ARCH) common drivers 
+SUBDIRS = xsm acm arch/$(TARGET_ARCH) common drivers
 define all_sources
     ( find include/asm-$(TARGET_ARCH) -name SCCS -prune -o -name '*.h' -print; \
       find include -type d -name SCCS -prune -o \( -name "asm-*" -o \
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/Rules.mk
--- a/xen/Rules.mk    Fri May 26 09:23:33 2006 +0100
+++ b/xen/Rules.mk    Thu Aug 31 17:14:49 2006 -0400
@@ -47,10 +47,12 @@ HDRS := $(subst $(BASEDIR)/include/xen/c
 # 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-y               += -DXSM_ENABLE
 CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY
 CFLAGS-$(verbose)      += -DVERBOSE
 CFLAGS-$(crash_debug)  += -DCRASH_DEBUG
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/arch/x86/dom0_ops.c    Thu Aug 31 17:14:49 2006 -0400
@@ -25,6 +25,7 @@
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
 #include <public/sched_ctl.h>
+#include <xsm/xsm.h>
 
 #include <asm/mtrr.h>
 #include "cpu/mtrr/mtrr.h"
@@ -58,6 +59,10 @@ long arch_do_dom0_op(struct dom0_op *op,
 
     case DOM0_MSR:
     {
+        ret = xsm_msr(op->u.msr.write);
+        if (ret)
+            break;
+            
         if ( op->u.msr.write )
         {
             msr_cpu_mask = op->u.msr.cpu_mask;
@@ -89,15 +94,25 @@ long arch_do_dom0_op(struct dom0_op *op,
         d = find_domain_by_id(op->u.shadow_control.domain);
         if ( d != NULL )
         {
+            ret = xsm_shadow_control(d, op->u.shadow_control.op);
+            if (ret)
+                goto shadowctrl_out;
+                
             ret = shadow_mode_control(d, &op->u.shadow_control);
+            copy_to_guest(u_dom0_op, op, 1);
+
+        shadowctrl_out:
             put_domain(d);
-            copy_to_guest(u_dom0_op, op, 1);
         } 
     }
     break;
 
     case DOM0_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,
@@ -115,6 +130,10 @@ long arch_do_dom0_op(struct dom0_op *op,
 
     case DOM0_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)
@@ -134,6 +153,10 @@ long arch_do_dom0_op(struct dom0_op *op,
         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 )
         {
@@ -150,6 +173,11 @@ long arch_do_dom0_op(struct dom0_op *op,
     case DOM0_MICROCODE:
     {
         extern int microcode_update(void *buf, unsigned long len);
+
+        ret = xsm_microcode();
+        if (ret)
+            break;
+            
         ret = microcode_update(op->u.microcode.data.p, op->u.microcode.length);
     }
     break;
@@ -169,6 +197,10 @@ long arch_do_dom0_op(struct dom0_op *op,
             op->u.ioport_permission.domain)) == NULL) )
             break;
 
+        ret = xsm_ioport_permission(d, fp, op->u.ioport_permission.allow_access);
+        if (ret)
+            goto ioportperm_out;
+            
         if ( np == 0 )
             ret = 0;
         else if ( op->u.ioport_permission.allow_access )
@@ -176,14 +208,20 @@ long arch_do_dom0_op(struct dom0_op *op,
         else
             ret = ioports_deny_access(d, fp, fp + np - 1);
 
+    ioportperm_out:
         put_domain(d);
     }
     break;
 
     case DOM0_PHYSINFO:
     {
+    
         dom0_physinfo_t *pi = &op->u.physinfo;
 
+        ret = xsm_physinfo();
+        if (ret)
+            break;
+            
         pi->threads_per_core =
             cpus_weight(cpu_sibling_map[0]);
         pi->cores_per_socket =
@@ -212,6 +250,10 @@ long arch_do_dom0_op(struct dom0_op *op,
 
         ret = -EINVAL;
 
+        ret = xsm_getpageframeinfo(mfn);
+        if (ret)
+            break;
+                        
         if ( unlikely(!mfn_valid(mfn)) ||
              unlikely((d = find_domain_by_id(dom)) == NULL) )
             break;
@@ -291,6 +333,10 @@ long arch_do_dom0_op(struct dom0_op *op,
                 struct page_info *page;
                 unsigned long mfn = l_arr[j];
 
+                ret = xsm_getpageframeinfo(mfn);
+                if (ret)
+                    break;
+            
                 page = mfn_to_page(mfn);
 
                 if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 
@@ -350,6 +396,10 @@ long arch_do_dom0_op(struct dom0_op *op,
         ret = -EINVAL;
         if ( d != NULL )
         {
+            ret = xsm_getmemlist(d);
+            if (ret)
+                goto getmemlist_out;
+        
             ret = 0;
 
             spin_lock(&d->page_alloc_lock);
@@ -371,6 +421,7 @@ long arch_do_dom0_op(struct dom0_op *op,
             op->u.getmemlist.num_pfns = i;
             copy_to_guest(u_dom0_op, op, 1);
             
+        getmemlist_out:
             put_domain(d);
         }
     }
@@ -380,6 +431,11 @@ long arch_do_dom0_op(struct dom0_op *op,
     {
         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:
@@ -409,6 +465,10 @@ long arch_do_dom0_op(struct dom0_op *op,
         struct dom0_memory_map_entry entry;
         int i;
 
+        ret = xsm_physmemmap();
+        if (ret)
+            break;
+            
         for ( i = 0; i < e820.nr_map; i++ )
         {
             if ( i >= op->u.physical_memory_map.max_map_entries )
@@ -436,6 +496,10 @@ long arch_do_dom0_op(struct dom0_op *op,
             op->u.hypercall_init.domain)) == NULL) )
             break;
 
+        ret = xsm_hypercall_init(d);
+        if (ret)
+            goto hypercallinit_out;
+            
         ret = -EACCES;
         if ( !mfn_valid(mfn) ||
              !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
@@ -452,6 +516,7 @@ long arch_do_dom0_op(struct dom0_op *op,
 
         put_page_and_type(mfn_to_page(mfn));
 
+    hypercallinit_out:
         put_domain(d);
     }
     break;
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/arch/x86/mm.c    Thu Aug 31 17:14:49 2006 -0400
@@ -105,6 +105,7 @@
 #include <asm/ldt.h>
 #include <asm/x86_emulate.h>
 #include <public/memory.h>
+#include <xsm/xsm.h>
 
 #ifdef VERBOSE
 #define MEM_LOG(_f, _a...)                           \
@@ -2083,6 +2084,10 @@ int do_mmu_update(
              */
         case MMU_NORMAL_PT_UPDATE:
 
+             rc = xsm_mmu_normal_update(d, req.val);
+             if (rc)
+                 goto out;
+             
             gmfn = req.ptr >> PAGE_SHIFT;
             mfn = gmfn_to_mfn(d, gmfn);
 
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/arch/x86/setup.c    Thu Aug 31 17:14:49 2006 -0400
@@ -24,6 +24,7 @@
 #include <asm/shadow.h>
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
+#include <xsm/xsm.h>
 
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(void);
@@ -404,6 +405,8 @@ void __init __start_xen(multiboot_info_t
 
     scheduler_init();
 
+    xsm_init(&initrdidx, mbi, initial_images_start);
+
     idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     BUG_ON(idle_domain == NULL);
 
@@ -507,6 +510,8 @@ void __init __start_xen(multiboot_info_t
     set_bit(_DOMF_privileged, &dom0->domain_flags);
     /* post-create hooks sets security label */
     acm_post_domain0_create(dom0->domain_id);
+
+    xsm_complete_init(dom0);
 
     /* Grab the DOM0 command line. */
     cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S    Fri May 26 09:23:33 2006 +0100
+++ b/xen/arch/x86/x86_32/entry.S    Thu Aug 31 17:14:49 2006 -0400
@@ -648,6 +648,7 @@ ENTRY(hypercall_table)
         .long do_acm_op
         .long do_nmi_op
         .long do_arch_sched_op
+        .long do_xsm_op             /* 30 */
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -683,6 +684,7 @@ ENTRY(hypercall_args_table)
         .byte 1 /* do_acm_op            */
         .byte 2 /* do_nmi_op            */
         .byte 2 /* do_arch_sched_op     */
+        .byte 1 /* do_xsm_op            */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S    Fri May 26 09:23:33 2006 +0100
+++ b/xen/arch/x86/x86_32/xen.lds.S    Thu Aug 31 17:14:49 2006 -0400
@@ -56,6 +56,7 @@ SECTIONS
   __initcall_start = .;
   .initcall.init : { *(.initcall.init) } :text
   __initcall_end = .;
+  .xsm_initcall.init : { __xsm_initcall_start = .; *(.xsm_initcall.init) __xsm_initcall_end = .; }
   . = ALIGN(STACK_SIZE);
   __init_end = .;
 
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/common/dom0_ops.c    Thu Aug 31 17:14:49 2006 -0400
@@ -22,6 +22,7 @@
 #include <public/dom0_ops.h>
 #include <public/sched_ctl.h>
 #include <acm/acm_hooks.h>
+#include <xsm/xsm.h>
 
 extern long arch_do_dom0_op(
     struct dom0_op *op, GUEST_HANDLE(dom0_op_t) u_dom0_op);
@@ -82,6 +83,8 @@ static void getdomaininfo(struct domain 
         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;
@@ -120,7 +123,12 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         ret = -ESRCH;
         if ( d != NULL )
         {
+            ret = xsm_setvcpucontext(d);
+            if (ret) 
+                goto setvcpucontext_out;
+            
             ret = set_info_guest(d, &op->u.setvcpucontext);
+        setvcpucontext_out:
             put_domain(d);
         }
     }
@@ -132,12 +140,18 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         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:
             put_domain(d);
         }
     }
@@ -146,9 +160,14 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
     case DOM0_UNPAUSEDOMAIN:
     {
         struct domain *d = find_domain_by_id(op->u.unpausedomain.domain);
+            
         ret = -ESRCH;
         if ( d != NULL )
         {
+            ret = xsm_unpausedomain(d);
+            if (ret) 
+                goto unpausedomain_out;
+
             ret = -EINVAL;
             if ( (d != current->domain) && 
                  test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
@@ -156,6 +175,8 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
                 domain_unpause_by_systemcontroller(d);
                 ret = 0;
             }
+            
+        unpausedomain_out:
             put_domain(d);
         }
     }
@@ -178,12 +199,16 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( supervisor_mode_kernel )
             return -EINVAL;
 
+        ret = xsm_createdomain(op);
+        if (ret)
+            goto createdomain_out;
+            
         dom = op->u.createdomain.domain;
         if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
         {
             ret = -EINVAL;
             if ( !is_free_domid(dom) )
-                break;
+                goto createdomain_out;
         }
         else
         {
@@ -197,7 +222,7 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
             ret = -ENOMEM;
             if ( dom == rover )
-                break;
+                goto createdomain_out;
 
             rover = dom;
         }
@@ -232,7 +257,9 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
         ret = -ENOMEM;
         if ( (d = domain_create(dom, pro)) == NULL )
-            break;
+            goto createdomain_out;
+
+        xsm_createdomain_post(d, op);
 
         memcpy(d->handle, op->u.createdomain.handle,
                sizeof(xen_domain_handle_t));
@@ -240,8 +267,13 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         ret = 0;
 
         op->u.createdomain.domain = d->domain_id;
-        if ( copy_to_guest(u_dom0_op, op, 1) )
-            ret = -EFAULT;
+
+    createdomain_out:        
+        if (ret)
+            xsm_createdomain_fail(op);
+
+        if ( copy_to_guest(u_dom0_op, op, 1) )
+            ret = -EFAULT;    
     }
     break;
 
@@ -258,6 +290,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL )
             break;
 
+        ret = xsm_max_vcpus(d);
+        if (ret)
+            goto maxvcpu_out;
+        
         /*
          * Can only create new VCPUs while the domain is not fully constructed
          * (and hence not runnable). Xen needs auditing for races before
@@ -293,17 +329,24 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
     case DOM0_DESTROYDOMAIN:
     {
         struct domain *d = find_domain_by_id(op->u.destroydomain.domain);
+
         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;
             }
-            put_domain(d);
-        }
+            
+        destroydomain_out:
+            put_domain(d);
+        }        
     }
     break;
 
@@ -320,6 +363,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
             break;
         }
         
+        ret = xsm_setvcpuaffinity(d);
+        if (ret) 
+            goto setvcpuaffinity_out;
+                    
         if ( (op->u.setvcpuaffinity.vcpu >= MAX_VIRT_CPUS) ||
              !d->vcpu[op->u.setvcpuaffinity.vcpu] )
         {
@@ -350,13 +397,17 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
                    (int)sizeof(op->u.setvcpuaffinity.cpumap)));
 
         ret = vcpu_set_affinity(v, &new_affinity);
-
+    
+    setvcpuaffinity_out:
         put_domain(d);
     }
     break;
 
     case DOM0_SCHEDCTL:
     {
+        ret = xsm_schedctl(&op->u.schedctl);
+        if (ret)
+            break;
         ret = sched_ctl(&op->u.schedctl);
         if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
@@ -365,6 +416,9 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
     case DOM0_ADJUSTDOM:
     {
+        ret = xsm_adjustdom(&op->u.adjustdom);
+        if (ret)
+            break;
         ret = sched_adjdom(&op->u.adjustdom);
         if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
@@ -397,11 +451,16 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
         read_unlock(&domlist_lock);
 
+        ret = xsm_getdomaininfo(d);
+        if (ret) 
+            goto getdomaininfo_out;
+        
         getdomaininfo(d, &op->u.getdomaininfo);
 
         if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
 
+    getdomaininfo_out:
         put_domain(d);
     }
     break;
@@ -426,6 +485,12 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
                 break;
             }
 
+            ret = xsm_getdomaininfo(d);
+            if (ret) {
+                put_domain(d);
+                continue;
+            }
+                
             getdomaininfo(d, &info);
 
             put_domain(d);
@@ -461,7 +526,11 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         ret = -ESRCH;
         if ( (d = find_domain_by_id(op->u.getvcpucontext.domain)) == NULL )
             break;
-
+            
+        ret = xsm_getvcpucontext(d);
+        if (ret) 
+            goto getvcpucontext_out;
+        
         ret = -EINVAL;
         if ( op->u.getvcpucontext.vcpu >= MAX_VIRT_CPUS )
             goto getvcpucontext_out;
@@ -510,6 +579,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( (d = find_domain_by_id(op->u.getvcpuinfo.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;
@@ -542,6 +615,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
     case DOM0_SETTIME:
     {
+        ret = xsm_settime();
+        if (ret)
+            break;
+            
         do_settime(op->u.settime.secs, 
                    op->u.settime.nsecs, 
                    op->u.settime.system_time);
@@ -551,6 +628,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
     case DOM0_TBUFCONTROL:
     {
+        ret = xsm_tbufcontrol();
+        if (ret)
+            break;
+            
         ret = tb_control(&op->u.tbufcontrol);
         if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
@@ -559,6 +640,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
     
     case DOM0_READCONSOLE:
     {
+        ret = xsm_readconsole(op->u.readconsole.clear);
+        if (ret)
+            break;
+            
         ret = read_console_ring(
             op->u.readconsole.buffer, 
             &op->u.readconsole.count,
@@ -570,6 +655,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 
     case DOM0_SCHED_ID:
     {
+        ret = xsm_sched_id();
+        if (ret)
+            break;
+            
         op->u.sched_id.sched_id = sched_id();
         if ( copy_to_guest(u_dom0_op, op, 1) )
             ret = -EFAULT;
@@ -588,6 +677,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( d == NULL )
             break;
 
+        xsm_setdomainmaxmem(d);
+        if (ret) 
+            goto setdomainmaxmem_out;
+        
         ret = -EINVAL;
         new_max = op->u.setdomainmaxmem.max_memkb >> (PAGE_SHIFT-10);
 
@@ -599,6 +692,7 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         }
         spin_unlock(&d->page_alloc_lock);
 
+    setdomainmaxmem_out:
         put_domain(d);
     }
     break;
@@ -610,10 +704,16 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         d = find_domain_by_id(op->u.setdomainhandle.domain);
         if ( d != NULL )
         {
+            ret = xsm_setdomainhandle(d);
+            if (ret)
+                goto setdomainhandle_out;
+                
             memcpy(d->handle, op->u.setdomainhandle.handle,
                    sizeof(xen_domain_handle_t));
-            put_domain(d);
             ret = 0;
+
+        setdomainhandle_out:    
+            put_domain(d);
         }
     }
     break;
@@ -625,12 +725,18 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         d = find_domain_by_id(op->u.setdebugging.domain);
         if ( d != NULL )
         {
+            ret = xsm_setdebugging(d);
+            if (ret)
+                goto setdebugging_out;
+                
             if ( op->u.setdebugging.enable )
                 set_bit(_DOMF_debugging, &d->domain_flags);
             else
                 clear_bit(_DOMF_debugging, &d->domain_flags);
-            put_domain(d);
             ret = 0;
+
+        setdebugging_out:
+            put_domain(d);
         }
     }
     break;
@@ -649,11 +755,16 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( d == NULL )
             break;
 
+        ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
+        if (ret)
+            goto irqperm_out;
+            
         if ( op->u.irq_permission.allow_access )
             ret = irq_permit_access(d, pirq);
         else
             ret = irq_deny_access(d, pirq);
 
+    irqperm_out:
         put_domain(d);
     }
     break;
@@ -673,11 +784,16 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
         if ( d == NULL )
             break;
 
+        ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
+        if (ret)
+            goto iomemperm_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);
 
+    iomemperm_out:
         put_domain(d);
     }
     break;
@@ -685,6 +801,10 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) 
 #ifdef PERF_COUNTERS
     case DOM0_PERFCCONTROL:
     {
+        ret = xsm_perfcontrol(void);
+        if (ret)
+            break;
+            
         extern int perfc_control(dom0_perfccontrol_t *);
         ret = perfc_control(&op->u.perfccontrol);
         if ( copy_to_guest(u_dom0_op, op, 1) )
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/common/domain.c
--- a/xen/common/domain.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/common/domain.c    Thu Aug 31 17:14:49 2006 -0400
@@ -24,6 +24,7 @@
 #include <public/dom0_ops.h>
 #include <public/sched.h>
 #include <public/vcpu.h>
+#include <xsm/xsm.h>
 
 /* Both these structures are protected by the domlist_lock. */
 rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
@@ -50,6 +51,9 @@ struct domain *domain_create(domid_t dom
     INIT_LIST_HEAD(&d->xenpage_list);
 
     rangeset_domain_initialise(d);
+
+    if (xsm_alloc_security_domain(d))
+        goto fail1;
 
     if ( !is_idle_domain(d) )
     {
@@ -305,6 +309,8 @@ void domain_destroy(struct domain *d)
 
     arch_domain_destroy(d);
 
+    xsm_free_security_domain(d);
+
     free_domain(d);
 
     send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/common/event_channel.c
--- a/xen/common/event_channel.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/common/event_channel.c    Thu Aug 31 17:14:49 2006 -0400
@@ -29,6 +29,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])
@@ -61,9 +62,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;
 }
 
@@ -89,6 +96,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 )
@@ -143,6 +154,10 @@ static long evtchn_bind_interdomain(evtc
          (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;
     lchn->state                     = ECS_INTERDOMAIN;
@@ -193,6 +208,11 @@ static long evtchn_bind_virq(evtchn_bind
         ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
+    
+    rc = xsm_evtchn_virq(d, chn, virq, vcpu);
+    if (rc)
+        goto out;
+        
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
@@ -222,6 +242,11 @@ static long evtchn_bind_ipi(evtchn_bind_
         ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
+    
+    rc = xsm_evtchn_ipi(d, chn, vcpu);
+    if (rc)
+        goto out;
+        
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
 
@@ -257,6 +282,10 @@ static long evtchn_bind_pirq(evtchn_bind
 
     chn = evtchn_from_port(d, port);
 
+    rc = xsm_evtchn_pirq(d, chn, pirq);
+    if (rc)
+        goto out;
+        
     d->pirq_to_evtchn[pirq] = port;
     rc = pirq_guest_bind(d->vcpu[0], pirq, 
                          !!(bind->flags & BIND_PIRQ__WILL_SHARE));
@@ -296,6 +325,11 @@ static long __evtchn_close(struct domain
     }
 
     chn1 = evtchn_from_port(d1, port1);
+    
+    rc = xsm_evtchn_close(d1, chn1);
+    if (rc)
+        goto out;
+        
     switch ( chn1->state )
     {
     case ECS_FREE:
@@ -415,6 +449,11 @@ long evtchn_send(unsigned int lport)
     }
 
     lchn = evtchn_from_port(ld, lport);
+
+    ret = xsm_evtchn_send(ld, lchn);
+    if (ret)
+        goto out;
+        
     switch ( lchn->state )
     {
     case ECS_INTERDOMAIN:
@@ -433,6 +472,7 @@ long evtchn_send(unsigned int lport)
         ret = -EINVAL;
     }
 
+out:
     spin_unlock(&ld->evtchn_lock);
 
     return ret;
@@ -511,6 +551,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:
@@ -568,6 +613,11 @@ long evtchn_bind_vcpu(unsigned int port,
     }
 
     chn = evtchn_from_port(d, port);
+    
+    rc = xsm_evtchn_vcpu(d, chn, vcpu_id);
+    if (rc)
+        goto out;
+        
     switch ( chn->state )
     {
     case ECS_UNBOUND:
@@ -591,6 +641,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);
 
@@ -600,8 +652,13 @@ 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];
+
+    ret = xsm_evtchn_unmask(d, chn);
+    if (ret)
+        goto out;
+        
     /*
      * These operations must happen in strict order. Based on
      * include/xen/event.h:evtchn_set_pending(). 
@@ -615,9 +672,10 @@ static long evtchn_unmask(evtchn_unmask_
         evtchn_notify(v);
     }
 
+out:
     spin_unlock(&d->evtchn_lock);
 
-    return 0;
+    return ret;
 }
 
 long do_event_channel_op(GUEST_HANDLE(evtchn_op_t) uop)
@@ -696,10 +754,16 @@ long do_event_channel_op(GUEST_HANDLE(ev
 
 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;
+    if (xsm_evtchn_init(d, chn))
+        return -EACCES;
+        
     return 0;
 }
 
@@ -711,8 +775,10 @@ void evtchn_destroy(struct domain *d)
     for ( i = 0; port_is_valid(d, i); i++ )
             (void)__evtchn_close(d, i);
 
-    for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
+    for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ ) {
+        xsm_free_security_evtchn(d->evtchn[i]);
         xfree(d->evtchn[i]);
+    }
 }
 
 /*
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/common/grant_table.c
--- a/xen/common/grant_table.c    Fri May 26 09:23:33 2006 +0100
+++ b/xen/common/grant_table.c    Thu Aug 31 17:14:49 2006 -0400
@@ -31,6 +31,7 @@
 #include <xen/trace.h>
 #include <xen/guest_access.h>
 #include <acm/acm_hooks.h>
+#include <xsm/xsm.h>
 
 #define PIN_FAIL(_lbl, _rc, _f, _a...)          \
     do {                                        \
@@ -120,6 +121,14 @@ __gnttab_map_grant_ref(
         return;
     }
 
+    rc = xsm_grant_mapref(ld, rd, op->flags);
+    if (rc)
+    {
+        put_domain(rd);
+        op->status = GNTST_permission_denied;
+        return;
+    }
+
     /* Get a maptrack handle. */
     if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
     {
@@ -361,6 +370,14 @@ __gnttab_unmap_grant_ref(
         return;
     }
 
+    rc = xsm_grant_unmapref(ld, rd);
+    if (rc)
+    {
+        put_domain(rd);
+        op->status = GNTST_permission_denied;
+        return;
+    }
+    
     TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
 
     act = &rd->grant_table->active[ref];
@@ -506,6 +523,13 @@ gnttab_setup_table(
         goto out;
     }
 
+    if ( xsm_grant_setup(current->domain, d) )
+    {
+        put_domain(d);
+        op.status = GNTST_permission_denied;
+        goto out;
+    }
+    
     if ( op.nr_frames <= NR_GRANT_FRAMES )
     {
         ASSERT(d->grant_table != NULL);
@@ -653,6 +677,12 @@ gnttab_transfer(
             goto copyback;
         }
 
+        if ( xsm_grant_transfer(d, e) )
+        {
+            gop.status = GNTST_permission_denied;
+            goto copyback;
+        }
+        
         spin_lock(&e->page_alloc_lock);
 
         /*
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/public/xen.h
--- a/xen/include/public/xen.h    Fri May 26 09:23:33 2006 +0100
+++ b/xen/include/public/xen.h    Thu Aug 31 17:14:49 2006 -0400
@@ -60,6 +60,7 @@
 #define __HYPERVISOR_acm_op               27
 #define __HYPERVISOR_nmi_op               28
 #define __HYPERVISOR_sched_op             29
+#define __HYPERVISOR_xsm_op               30
 
 /* 
  * VIRTUAL INTERRUPTS
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h    Fri May 26 09:23:33 2006 +0100
+++ b/xen/include/xen/grant_table.h    Thu Aug 31 17:14:49 2006 -0400
@@ -74,6 +74,7 @@ typedef struct {
     grant_entry_t        *shared;
     /* Active grant table. */
     active_grant_entry_t *active;
+    void                 *security;
     /* Mapping tracking table. */
     grant_mapping_t      *maptrack;
     unsigned int          maptrack_head;
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h    Fri May 26 09:23:33 2006 +0100
+++ b/xen/include/xen/hypercall.h    Thu Aug 31 17:14:49 2006 -0400
@@ -12,6 +12,7 @@
 #include <public/acm_ops.h>
 #include <public/event_channel.h>
 #include <asm/hypercall.h>
+#include <xsm/xsm.h>
 
 extern long
 do_ni_hypercall(
@@ -82,6 +83,10 @@ do_acm_op(
     GUEST_HANDLE(acm_op_t) u_acm_op);
 
 extern long
+do_xsm_op(
+    GUEST_HANDLE(xsm_op_t) u_xsm_op);
+
+extern long
 do_nmi_op(
     unsigned int cmd,
     GUEST_HANDLE(void) arg);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/xen/sched.h
--- a/xen/include/xen/sched.h    Fri May 26 09:23:33 2006 +0100
+++ b/xen/include/xen/sched.h    Thu Aug 31 17:14:49 2006 -0400
@@ -47,6 +47,7 @@ struct evtchn
         u16 pirq;      /* state == ECS_PIRQ */
         u16 virq;      /* state == ECS_VIRQ */
     } u;
+    void *ssid;
 };
 
 int  evtchn_init(struct domain *d);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/xsm/xsm.h
--- /dev/null    Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h    Thu Aug 31 17:14:49 2006 -0400
@@ -0,0 +1,722 @@
+/*
+ *  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.
+ */
+
+#ifndef __XSM_H__
+#define __XSM_H__
+
+#include <xen/sched.h>
+#include <xen/multiboot.h>
+
+#ifdef XSM_ENABLE
+
+/* policy magic number (defined by XSM_MAGIC) */
+typedef u32 xsm_magic_t;
+#ifndef XSM_MAGIC
+#define XSM_MAGIC 0x00000000
+#endif
+
+extern char *policy_buffer;
+extern u32 policy_size;
+
+typedef void xsm_op_t;
+DEFINE_GUEST_HANDLE(xsm_op_t);
+
+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, dom0_getdomaininfo_t *info);
+    int (*setvcpucontext) (struct domain *d);
+    int (*pausedomain) (struct domain *d);
+    int (*unpausedomain) (struct domain *d);
+    int (*createdomain) (dom0_op_t *op);
+    void (*createdomain_post) (struct domain *d, dom0_op_t *op);
+    void (*createdomain_fail) (dom0_op_t *op);
+    int (*max_vcpus) (struct domain *d);
+    int (*destroydomain) (struct domain *d);
+    int (*setvcpuaffinity) (struct domain *d);
+    int (*schedctl) (struct sched_ctl_cmd *cmd);
+    int (*adjustdom) (struct sched_adjdom_cmd *cmd);
+    int (*getdomaininfo) (struct domain *d);
+    int (*getvcpucontext) (struct domain *d);
+    int (*getvcpuinfo) (struct domain *d);
+    int (*settime) (void);
+    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 (*msr) (uint32_t);
+    int (*shadow_control) (struct domain *d, uint32_t op);
+    int (*memtype) (uint32_t access);
+    int (*microcode) (void);
+    int (*ioport_permission) (struct domain *d, uint32_t ioport, uint8_t access);
+    int (*physinfo) (void);
+    int (*getpageframeinfo) (unsigned long mfn);
+    int (*getmemlist) (struct domain *d);
+    int (*platform_quirk) (uint32_t);
+    int (*physmemmap) (void);
+    int (*hypercall_init) (struct domain *d);
+    
+    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);
+    int (*evtchn_virq) (struct domain *d, struct evtchn *chn, int virq, int vcpu);
+    int (*evtchn_ipi) (struct domain *d, struct evtchn *chn, int vcpu);
+    int (*evtchn_pirq) (struct domain *d, struct evtchn *chn, int pirq);
+    int (*evtchn_close) (struct domain *d, struct evtchn *chn);
+    int (*evtchn_send) (struct domain *d, struct evtchn *chn);
+    int (*evtchn_status) (struct domain *d, struct evtchn *chn);
+    int (*evtchn_vcpu) (struct domain *d, struct evtchn *chn, unsigned int vcpu);
+    int (*evtchn_unmask) (struct domain *d, struct evtchn *chn);
+    int (*evtchn_init) (struct domain *d, struct evtchn *chn);
+
+    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 (*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 (*mmu_normal_update) (struct domain *d, intpte_t fpte);
+
+    long (*__do_xsm_op) (GUEST_HANDLE(xsm_op_t) op);
+    void (*complete_init) (struct domain *d);
+};
+
+extern struct xsm_operations *xsm_ops;
+
+static inline void xsm_security_domaininfo (struct domain *d, dom0_getdomaininfo_t *info)
+{
+    xsm_ops->security_domaininfo(d, info);
+}
+
+static inline int xsm_setvcpucontext(struct domain *d)
+{
+    return xsm_ops->setvcpucontext(d);
+}
+
+static inline int xsm_pausedomain (struct domain *d)
+{
+    return xsm_ops->pausedomain(d);
+}
+
+static inline int xsm_unpausedomain (struct domain *d)
+{
+    return xsm_ops->unpausedomain(d);
+}
+
+static inline int xsm_createdomain (dom0_op_t *op)
+{
+    return xsm_ops->createdomain(op);
+}
+
+static inline void xsm_createdomain_post (struct domain *d, dom0_op_t *op)
+{
+    xsm_ops->createdomain_post(d, op);
+}
+
+static inline void xsm_createdomain_fail (dom0_op_t *op)
+{
+    xsm_ops->createdomain_fail(op);
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+    return xsm_ops->max_vcpus(d);
+}
+
+static inline int xsm_destroydomain (struct domain *d)
+{
+    return xsm_ops->destroydomain(d);
+}
+
+static inline int xsm_setvcpuaffinity (struct domain *d)
+{
+    return xsm_ops->setvcpuaffinity(d);
+}
+
+static inline int xsm_schedctl (struct sched_ctl_cmd *cmd)
+{
+    return xsm_ops->schedctl(cmd);
+}
+
+static inline int xsm_adjustdom (struct sched_adjdom_cmd *cmd)
+{
+    return xsm_ops->adjustdom(cmd);
+}
+
+static inline int xsm_getdomaininfo (struct domain *d)
+{
+    return xsm_ops->getdomaininfo(d);
+}
+
+static inline int xsm_getvcpucontext (struct domain *d)
+{
+    return xsm_ops->getvcpucontext(d);
+}
+
+static inline int xsm_getvcpuinfo (struct domain *d)
+{
+    return xsm_ops->getvcpuinfo(d);
+}
+
+static inline int xsm_settime (void)
+{
+    return xsm_ops->settime();
+}
+
+static inline int xsm_tbufcontrol (void)
+{
+    return xsm_ops->tbufcontrol();
+}
+
+static inline int xsm_readconsole (uint32_t clear)
+{
+    return xsm_ops->readconsole(clear);
+}
+
+static inline int xsm_sched_id (void)
+{
+    return xsm_ops->sched_id();
+}
+
+static inline int xsm_setdomainmaxmem (struct domain *d)
+{
+    return xsm_ops->setdomainmaxmem(d);
+}
+
+static inline int xsm_setdomainhandle (struct domain *d)
+{
+    return xsm_ops->setdomainhandle(d);
+}
+
+static inline int xsm_setdebugging (struct domain *d)
+{
+    return xsm_ops->setdebugging(d);
+}
+
+static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, uint8_t access)
+{
+    return xsm_ops->irq_permission(d, pirq, access);
+} 
+
+static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, uint8_t access)
+{
+    return xsm_ops->iomem_permission(d, mfn, access);
+}
+
+static inline int xsm_perfconrol (void)
+{
+    return xsm_ops->perfcontrol();
+}
+
+static inline int xsm_msr (uint32_t access)
+{
+    return xsm_ops->msr(access);
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+    return xsm_ops->shadow_control(d, op);
+}
+
+static inline int xsm_memtype (uint32_t access)
+{
+    return xsm_ops->memtype(access);
+}
+
+static inline int xsm_microcode (void)
+{
+    return xsm_ops->microcode();
+}
+
+static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access)
+{
+    return xsm_ops->ioport_permission(d, ioport, access);
+}
+
+static inline int xsm_physinfo (void)
+{
+    return xsm_ops->physinfo();
+}
+
+static inline int xsm_getpageframeinfo (unsigned long mfn)
+{
+    return xsm_ops->getpageframeinfo(mfn);
+}
+
+static inline int xsm_getmemlist (struct domain *d)
+{
+    return xsm_ops->getmemlist(d);
+}
+
+static inline int xsm_platform_quirk (uint32_t quirk)
+{
+    return xsm_ops->platform_quirk(quirk);
+}
+
+static inline int xsm_physmemmap (void)
+{
+    return xsm_ops->physmemmap();
+}
+
+static inline int xsm_hypercall_init (struct domain *d)
+{
+    return xsm_ops->hypercall_init(d);
+}
+
+static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, 
+                                            domid_t id2)
+{
+    return xsm_ops->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_ops->evtchn_interdomain(d1, chan1, d2, chan2);
+}
+
+static inline int xsm_evtchn_virq (struct domain *d, struct evtchn *chn,
+                                                            int virq, int vcpu)
+{
+    return xsm_ops->evtchn_virq(d, chn, virq, vcpu);
+}
+
+static inline int xsm_evtchn_ipi (struct domain *d, struct evtchn *chn, int vcpu)
+{
+    return xsm_ops->evtchn_ipi(d, chn, vcpu);
+}
+
+static inline int xsm_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq)
+{
+    return xsm_ops->evtchn_pirq(d, chn, pirq);
+}
+
+static inline int xsm_evtchn_close (struct domain *d, struct evtchn *chn)
+{
+    return xsm_ops->evtchn_close(d, chn);
+}
+
+static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn)
+{
+    return xsm_ops->evtchn_send(d, chn);
+}
+
+static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn)
+{
+    return xsm_ops->evtchn_status(d, chn);
+}
+
+static inline int xsm_evtchn_vcpu (struct domain *d, struct evtchn *chn,
+                                                            unsigned int vcpu)
+{
+    return xsm_ops->evtchn_vcpu(d, chn, vcpu);
+}
+
+static inline int xsm_evtchn_unmask (struct domain *d, struct evtchn *chn)
+{
+    return xsm_ops->evtchn_unmask(d, chn);
+}
+
+static inline int xsm_evtchn_init (struct domain *d, struct evtchn *chn)
+{
+    return xsm_ops->evtchn_init(d, chn);
+}
+
+static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, 
+                                                                uint32_t flags)
+{
+    return xsm_ops->grant_mapref(d1, d2, flags);
+}
+
+static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2)
+{
+    return xsm_ops->grant_unmapref(d1, d2);        
+}
+
+static inline int xsm_grant_setup (struct domain *d1, struct domain *d2)
+{
+    return xsm_ops->grant_setup(d1, d2);
+}
+
+static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2)
+{
+    return xsm_ops->grant_transfer(d1, d2);
+}
+
+static inline int xsm_alloc_security_domain (struct domain *d)
+{
+    return xsm_ops->alloc_security_domain(d);
+}
+
+static inline void xsm_free_security_domain (struct domain *d)
+{
+    xsm_ops->free_security_domain(d);
+}
+
+static inline int xsm_alloc_security_evtchn (struct evtchn *chn)
+{
+    return xsm_ops->alloc_security_evtchn(chn);
+}
+
+static inline void xsm_free_security_evtchn (struct evtchn *chn)
+{
+    xsm_ops->free_security_evtchn(chn);
+}
+
+static inline int xsm_mmu_normal_update (struct domain *d, intpte_t fpte)
+{
+    return xsm_ops->mmu_normal_update(d, fpte);
+}
+
+static inline long __do_xsm_op (GUEST_HANDLE(xsm_op_t) op)
+{
+    return xsm_ops->__do_xsm_op(op);    
+}
+
+static inline void xsm_complete_init (struct domain *d)
+{
+    xsm_ops->complete_init(d);
+}
+
+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 void xsm_security_domaininfo (struct domain *d, dom0_getdomaininfo_t *info) 
+{
+    return;
+}
+
+static inline int xsm_setvcpucontext(struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_pausedomain (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_unpausedomain (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_createdomain (dom0_op_t *op)
+{
+    return 0;
+}
+
+static inline void xsm_createdomain_post (struct domain *d, dom0_op_t *op)
+{
+    return;
+}
+
+static inline void xsm_createdomain_fail (dom0_op_t *op)
+{
+    return;
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_destroydomain (struct domain *d1, struct domain *d2)
+{
+    return 0;
+}
+
+static inline int xsm_setvcpuaffinity (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_schedctl (struct sched_ctl_cmd *cmd)
+{
+    return 0;
+}
+
+static inline int xsm_adjustdom (struct sched_adjdom_cmd *cmd)
+{
+    return 0;
+}
+
+static inline int xsm_getdomaininfo (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_getvcpucontext (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_getvcpuinfo (struct domain d)
+{
+    return 0;
+}
+
+static inline int xsm_settime (void)
+{
+    return 0;
+}
+
+static inline int xsm_tbufcontrol (void)
+{
+    return 0;
+}
+
+static inline int xsm_readconsole (uint32_t clear)
+{
+    return 0;
+}
+
+static inline int xsm_sched_id (void)
+{
+    return 0;
+}
+
+static inline int xsm_setdomainmaxmem (struct domain d)
+{
+    return 0;
+}
+
+static inline int xsm_setdomainhandle (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_setdebugging (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, uint8_t access)
+{
+    return 0;
+} 
+
+static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, uint8_t access)
+{
+    return 0;
+}
+
+static inline int xsm_perfconrol (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_msr (uint32_t access)
+{
+    return 0;
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+    return 0;
+}
+
+static inline int xsm_memtype (uint32_t access)
+{
+    return 0;
+}
+
+static inline int xsm_microcode (void)
+{
+    return 0;
+}
+
+static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access)
+{
+    return 0;
+}
+
+static inline int xsm_physinfo (void)
+{
+    return 0;
+}
+
+static inline int xsm_getpageframeinfo (unsigned long mfn)
+{
+    return 0;
+}
+
+static inline int xsm_getmemlist (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_platform_quirk (uint32_t quirk)
+{
+    return 0;
+}
+
+static inline int xsm_physmemmap (void)
+{
+    return 0;
+}
+
+static inline int xsm_hypercall_init (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, 
+                                            domid_t id2)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_interdomain (struct domain *d1, struct evtchn
+                *chan1, struct domain *d2, struct evtchn *chan2)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_virq (struct domain *d, struct evtchn *chn, 
+                                                            int virq, int vcpu)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_ipi (struct domain *d, struct evtchn *chn, int vcpu)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_close (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_vcpu (struct domain *d, struct evtchn *chn, 
+                                                            unsigned int vcpu)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_unmask (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline int xsm_evtchn_init (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, 
+                                                                uint32_t flags)
+{
+    return 0;
+}
+
+static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2)
+{
+    return 0;
+}
+
+static inline int xsm_grant_setup (struct domain *d1, struct domain *d2)
+{
+    return 0;
+}
+
+static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2)
+{
+    return 0;
+}
+
+static inline int xsm_alloc_security_domain (struct domain *d)
+{
+    return 0;
+}
+
+static inline void xsm_free_security_domain (struct domain *d)
+{
+    return;
+}
+
+static inline int xsm_alloc_security_evtchn (struct evtchn *chn)
+{
+    return 0;
+}
+
+static inline void xsm_free_security_evtchn (struct evtchn *chn)
+{
+    return;
+}
+
+static inline int xsm_mmu_normal_update (struct domain *d, intpte_t fpte)
+{
+    return 0;
+}
+
+static inline long __do_xsm_op (GUEST_HANDLE(xsm_op_t) op)
+{
+    return -ENOSYS;
+}
+
+static inline int xsm_complete_init (struct domain *d)
+{
+    return 0;
+}
+
+static inline int xsm_init (unsigned int *initrdidx, const multiboot_info_t *mbi,
+                            unsigned long initial_images_start)
+{
+    return 0;
+}
+
+#endif
+
+#endif
+
+extern long do_xsm_op (GUEST_HANDLE(xsm_op_t) op);
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/xsm/Makefile
--- /dev/null    Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile    Thu Aug 31 17:14:49 2006 -0400
@@ -0,0 +1,3 @@
+obj-y += xsm_core.o
+obj-y += xsm_policy.o
+obj-y += dummy.o
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/xsm/dummy.c
--- /dev/null    Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c    Thu Aug 31 17:14:49 2006 -0400
@@ -0,0 +1,392 @@
+/*
+ *  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>
+
+#ifdef XSM_ENABLE
+
+static void dummy_security_domaininfo(struct domain *d, dom0_getdomaininfo_t *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_createdomain(dom0_op_t *op)
+{
+    return 0;
+}
+
+static void dummy_createdomain_post (struct domain *d, dom0_op_t *op)
+{
+    return;
+}
+
+static void dummy_createdomain_fail (dom0_op_t *op)
+{
+    return;
+}
+
+static int dummy_max_vcpus(struct domain *d)
+{
+    return 0;
+}
+
+static int dummy_destroydomain (struct domain *d)
+{
+    return 0;
+}
+
+static int dummy_setvcpuaffinity (struct domain *d)
+{
+    return 0;
+}
+
+static int dummy_schedctl (struct sched_ctl_cmd *cmd)
+{
+    return 0;
+}
+
+static int dummy_adjustdom (struct sched_adjdom_cmd *cmd)
+{
+    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_settime (void)
+{
+    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_msr (uint32_t access)
+{
+    return 0;
+}
+
+static int dummy_shadow_control (struct domain *d, uint32_t op)
+{
+    return 0;
+}
+
+static int dummy_memtype (uint32_t access)
+{
+    return 0;
+}
+
+static int dummy_microcode (void)
+{
+    return 0;
+}
+
+static int dummy_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access)
+{
+    return 0;
+}
+
+static int dummy_physinfo (void)
+{
+    return 0;
+}
+
+static int dummy_getpageframeinfo (unsigned long mfn)
+{
+    return 0;
+}
+
+static int dummy_getmemlist (struct domain *d)
+{
+    return 0;
+}
+
+static int dummy_platform_quirk (uint32_t quirk)
+{
+    return 0;
+}
+
+static int dummy_physmemmap (void)
+{
+    return 0;
+}
+
+static int dummy_hypercall_init (struct domain *d)
+{
+    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_mmu_normal_update (struct domain *d, intpte_t fpte)
+{
+    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 int dummy_evtchn_virq (struct domain *d, struct evtchn *chn, 
+                                                        int virq, int vcpu)
+{
+    return 0;
+}
+
+static int dummy_evtchn_ipi (struct domain *d, struct evtchn *chn, int vcpu)
+{
+    return 0;
+}
+
+static int dummy_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq)
+{
+    return 0;
+}
+
+static int dummy_evtchn_close (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+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_vcpu (struct domain *d, struct evtchn *chn, 
+                                                        unsigned int vcpu_id)
+{
+    return 0;
+}
+
+static int dummy_evtchn_unmask (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static int dummy_alloc_security_evtchn (struct evtchn *chn)
+{
+    return 0;
+}
+
+static void dummy_free_security_evtchn (struct evtchn *chn)
+{
+    return;
+}
+
+static int dummy_evtchn_init (struct domain *d, struct evtchn *chn)
+{
+    return 0;
+}
+
+static void dummy_complete_init (struct domain *d)
+{
+    return;
+}
+
+static long dummy___do_xsm_op(GUEST_HANDLE(xsm_op_t) op)
+{
+    return -ENOSYS;
+}
+
+struct xsm_operations dummy_xsm_ops;
+
+#define set_to_dummy_if_null(ops, function)                        \
+    do {                                                        \
+        if (!ops->function) {                                    \
+            ops->function = dummy_##function;                    \
+            DPRINTK("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, createdomain);
+    set_to_dummy_if_null(ops, createdomain_post);
+    set_to_dummy_if_null(ops, createdomain_fail);
+    set_to_dummy_if_null(ops, max_vcpus);
+    set_to_dummy_if_null(ops, destroydomain);
+    set_to_dummy_if_null(ops, setvcpuaffinity);
+    set_to_dummy_if_null(ops, schedctl);
+    set_to_dummy_if_null(ops, adjustdom);
+    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, 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, msr);
+    set_to_dummy_if_null(ops, shadow_control);
+    set_to_dummy_if_null(ops, memtype);
+    set_to_dummy_if_null(ops, microcode);
+    set_to_dummy_if_null(ops, ioport_permission);
+    set_to_dummy_if_null(ops, physinfo);
+    set_to_dummy_if_null(ops, getpageframeinfo);
+    set_to_dummy_if_null(ops, getmemlist);
+    set_to_dummy_if_null(ops, platform_quirk);
+    set_to_dummy_if_null(ops, physmemmap);
+    set_to_dummy_if_null(ops, hypercall_init);
+
+    set_to_dummy_if_null(ops, evtchn_unbound);
+    set_to_dummy_if_null(ops, evtchn_interdomain);
+    set_to_dummy_if_null(ops, evtchn_virq);
+    set_to_dummy_if_null(ops, evtchn_pirq);
+    set_to_dummy_if_null(ops, evtchn_ipi);
+    set_to_dummy_if_null(ops, evtchn_close);
+    set_to_dummy_if_null(ops, evtchn_send);
+    set_to_dummy_if_null(ops, evtchn_status);
+    set_to_dummy_if_null(ops, evtchn_vcpu);
+    set_to_dummy_if_null(ops, evtchn_unmask);
+    set_to_dummy_if_null(ops, evtchn_init);
+
+    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, 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, mmu_normal_update);
+
+    set_to_dummy_if_null(ops, __do_xsm_op);
+    set_to_dummy_if_null(ops, complete_init);
+}
+
+#endif
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/xsm/xsm_core.c
--- /dev/null    Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c    Thu Aug 31 17:14:49 2006 -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 (GUEST_HANDLE(xsm_op_t) op)
+{
+    return __do_xsm_op(op);
+}
+
+
diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/xsm/xsm_policy.c
--- /dev/null    Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c    Thu Aug 31 17:14:49 2006 -0400
@@ -0,0 +1,77 @@
+/*
+ *  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 _policy_len;
+
+    if (mbi->mods_count > 1)
+        *initrdidx = 1;
+
+    /*
+     * 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--) {
+#if defined(__i386__)
+        _policy_start = (u32 *)(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
+#elif defined(__x86_64__)
+        _policy_start = __va(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
+#else
+#error Architecture unsupported by XSM
+#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) {
+                if (mbi->mods_count > 2) {
+                    *initrdidx = 2;
+                } else {
+                    *initrdidx = 0;
+                }
+            } else {
+                *initrdidx = 1;
+            }
+        
+            break;
+        
+        } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == XSM_MAGIC ) */
+    }
+    
+    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] 11+ messages in thread

end of thread, other threads:[~2006-09-05 19:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-01 16:58 [Xense-devel][RFC][PATCH][1/4] Xen Security Modules: XSM George S. Coker, II
2006-09-01 18:35 ` James Morris
2006-09-01 18:47   ` George S. Coker, II
2006-09-01 18:55 ` Chris Wright
2006-09-01 19:00   ` Chris Wright
2006-09-01 19:39     ` George S. Coker, II
2006-09-01 19:37   ` George S. Coker, II
2006-09-02  3:43     ` Reiner Sailer
2006-09-05 16:25       ` John McDermott (U.S. Navy Employee)
2006-09-05 19:00         ` George S. Coker, II
2006-09-01 19:46   ` James Morris

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.