* [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
@ 2007-03-08 15:28 George S. Coker, II
2007-03-08 15:59 ` Alex Williamson
2007-03-08 16:21 ` Keir Fraser
0 siblings, 2 replies; 17+ messages in thread
From: George S. Coker, II @ 2007-03-08 15:28 UTC (permalink / raw)
To: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 2028 bytes --]
This patch provides the basic XSM framework for x86_32/x86/64. It
includes a dummy module that implements call/return for each security
function.
The hooks implemented by this patch provide a framework for security
modules to interpose and complement the existing privileged hypercall
operationsin xen as well as interpose on the discretionary operations
between domains.
I have done very casual performance testing of the XSM in comparison to
native xen. The XSM (with or without the dummy module) has negligible
impact as measured by lmbench and kbench from either dom0 or domU. The
tests were conducted on xen running idle dom0's and idle domU's. The
micro-benchmarks can/do especially vary when a security module (other
than the dummy module) is in place. This is to be expected. The macro-
benchmarks for a specific security module tend to average out the micro-
benchmark variations but may not be representative of a real platform
workload.
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.
Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>
[-- Attachment #2: xsm-030707-xen-14282.diff --]
[-- Type: text/x-patch, Size: 91847 bytes --]
diff -r 8117f6684991 -r 68b27338e2e4 Config.mk
--- a/Config.mk Wed Mar 7 16:21:21 2007 +0000
+++ b/Config.mk Wed Mar 7 18:30:23 2007 -0500
@@ -56,6 +56,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 8117f6684991 -r 68b27338e2e4 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 Wed Mar 7 16:21:21 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 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 Wed Mar 7 16:21:21 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/Makefile
--- a/xen/Makefile Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/Makefile Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/Rules.mk
--- a/xen/Rules.mk Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/Rules.mk Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/domctl.c Wed Mar 7 18:30:23 2007 -0500
@@ -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,11 @@ 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 +70,12 @@ 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 +100,12 @@ 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);
@@ -166,6 +184,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)) )
@@ -225,6 +247,12 @@ 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);
@@ -264,6 +292,12 @@ 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;
@@ -298,6 +332,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) )
@@ -330,6 +368,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;
@@ -381,6 +423,12 @@ 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
@@ -407,6 +455,12 @@ 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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c Wed Mar 7 18:30:23 2007 -0500
@@ -715,6 +715,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;
@@ -758,6 +762,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;
@@ -801,6 +809,10 @@ static int hvmop_set_pci_link_route(
if ( d == NULL )
return -ESRCH;
+ rc = xsm_hvm_set_pci_link_route(d);
+ if (rc)
+ goto out;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto out;
@@ -845,6 +857,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) )
goto param_fail;
diff -r 8117f6684991 -r 68b27338e2e4 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/irq.c Wed Mar 7 18:30:23 2007 -0500
@@ -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,8 @@ 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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/mm.c Wed Mar 7 18:30:23 2007 -0500
@@ -109,6 +109,7 @@
#include <asm/e820.h>
#include <asm/hypercall.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -2017,6 +2018,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;
@@ -2296,6 +2301,10 @@ int do_mmu_update(
*/
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);
@@ -2386,6 +2395,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");
@@ -2720,6 +2733,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);
@@ -2976,6 +2993,12 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
return -ESRCH;
+ if (xsm_add_to_physmap(current->domain, d)) {
+ if (xatp.domid != DOMID_SELF)
+ rcu_unlock_domain(d);
+ return -EPERM;
+ }
+
switch ( xatp.space )
{
case XENMAPSPACE_shared_info:
@@ -3052,6 +3075,13 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
return -ESRCH;
+ rc = xsm_domain_memory_map(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;
@@ -3085,10 +3115,15 @@ 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;
if ( memmap.nr_entries < e820.nr_map + 1 )
diff -r 8117f6684991 -r 68b27338e2e4 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/physdev.c Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/platform_hypercall.c Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/setup.c Wed Mar 7 18:30:23 2007 -0500
@@ -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();
@@ -737,6 +740,8 @@ void __init __start_xen(multiboot_info_t
/* Post-create hook 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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/sysctl.c Wed Mar 7 18:30:23 2007 -0500
@@ -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)
@@ -36,6 +37,10 @@ long arch_do_sysctl(
{
xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo;
+ ret = xsm_physinfo();
+ if (ret)
+ break;
+
pi->threads_per_core =
cpus_weight(cpu_sibling_map[0]);
pi->cores_per_socket =
diff -r 8117f6684991 -r 68b27338e2e4 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/entry.S Wed Mar 7 18:30:23 2007 -0500
@@ -671,6 +671,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
@@ -714,6 +715,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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/mm.c Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/xen.lds.S Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_64/entry.S Wed Mar 7 18:30:23 2007 -0500
@@ -587,6 +587,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
@@ -630,6 +631,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 8117f6684991 -r 68b27338e2e4 xen/common/domain.c
--- a/xen/common/domain.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/domain.c Wed Mar 7 18:30:23 2007 -0500
@@ -28,6 +28,7 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#include <xsm/xsm.h>
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
@@ -156,6 +157,9 @@ struct domain *domain_create(domid_t dom
d->is_hvm = 1;
rangeset_domain_initialise(d);
+
+ if (xsm_alloc_security_domain(d))
+ goto fail1;
if ( !is_idle_domain(d) )
{
@@ -357,6 +361,8 @@ static void complete_domain_destroy(stru
arch_domain_destroy(d);
+ xsm_free_security_domain(d);
+
free_domain(d);
send_guest_global_virq(dom0, VIRQ_DOM_EXC);
diff -r 8117f6684991 -r 68b27338e2e4 xen/common/domctl.c
--- a/xen/common/domctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/domctl.c Wed Mar 7 18:30:23 2007 -0500
@@ -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;
@@ -207,6 +210,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;
+ ret = xsm_setvcpucontext(d);
+ if (ret)
+ goto svc_out;
+
ret = -EINVAL;
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
goto svc_out;
@@ -254,12 +261,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);
}
}
@@ -271,6 +283,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_unpausedomain(d);
+ if (ret)
+ goto unpausedomain_out;
+
ret = -EINVAL;
if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
@@ -278,6 +294,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
domain_unpause_by_systemcontroller(d);
ret = 0;
}
+
+ unpausedomain_out:
rcu_unlock_domain(d);
}
}
@@ -291,10 +309,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_resumedomain(d);
+ if (ret)
+ goto resumedomain_out;
+
ret = 0;
if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) )
for_each_vcpu ( d, v )
vcpu_wake(v);
+
+ resumedomain_out:
rcu_unlock_domain(d);
}
}
@@ -310,6 +334,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( supervisor_mode_kernel ||
(op->u.createdomain.flags & ~XEN_DOMCTL_CDF_hvm_guest) )
return -EINVAL;
+
+ ret = xsm_createdomain(op);
+ if (ret)
+ goto createdomain_out;
dom = op->domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
@@ -343,12 +371,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = domain_create(dom, domcr_flags)) == NULL )
break;
+ xsm_createdomain_post(d, op);
+
ret = 0;
memcpy(d->handle, op->u.createdomain.handle,
sizeof(xen_domain_handle_t));
op->domain = d->domain_id;
+
+ createdomain_out:
+ if (ret)
+ xsm_createdomain_fail(op);
+
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
}
@@ -365,6 +400,10 @@ 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)
break;
/* Needed, for example, to ensure writable p.t. state is synced. */
@@ -403,12 +442,17 @@ 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);
}
}
@@ -426,6 +470,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;
@@ -460,10 +508,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;
@@ -492,12 +545,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;
@@ -511,6 +569,12 @@ 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 )
@@ -568,6 +632,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;
@@ -603,6 +671,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);
@@ -617,6 +689,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
spin_unlock(&d->page_alloc_lock);
+ max_mem_out:
rcu_unlock_domain(d);
}
break;
@@ -628,6 +701,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdomainhandle(d);
+ if (ret) {
+ rcu_unlock_domain(d);
+ break;
+ }
memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
rcu_unlock_domain(d);
@@ -643,6 +721,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdebugging(d);
+ if (ret) {
+ rcu_unlock_domain(d);
+ break;
+ }
+
if ( op->u.setdebugging.enable )
set_bit(_DOMF_debugging, &d->domain_flags);
else
@@ -667,11 +751,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;
@@ -690,12 +779,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;
@@ -708,6 +802,11 @@ 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 8117f6684991 -r 68b27338e2e4 xen/common/event_channel.c
--- a/xen/common/event_channel.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/event_channel.c Wed Mar 7 18:30:23 2007 -0500
@@ -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,9 +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 +127,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 )
@@ -177,6 +188,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;
@@ -231,6 +246,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;
@@ -261,6 +281,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;
@@ -296,6 +321,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));
@@ -342,7 +371,11 @@ static long __evtchn_close(struct domain
rc = -EINVAL;
goto out;
}
-
+
+ rc = xsm_evtchn_close(d1, chn1);
+ if (rc)
+ goto out;
+
switch ( chn1->state )
{
case ECS_FREE:
@@ -426,6 +459,7 @@ static long __evtchn_close(struct domain
/* Reset binding to vcpu0 when the channel is freed. */
chn1->state = ECS_FREE;
chn1->notify_vcpu_id = 0;
+ xsm_evtchn_close_post(chn1);
out:
if ( d2 != NULL )
@@ -470,6 +504,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 +538,7 @@ long evtchn_send(unsigned int lport)
ret = -EINVAL;
}
+out:
spin_unlock(&ld->evtchn_lock);
return ret;
@@ -610,6 +649,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:
@@ -676,6 +720,10 @@ long evtchn_bind_vcpu(unsigned int port,
goto out;
}
+ rc = xsm_evtchn_vcpu(d, chn, vcpu_id);
+ if (rc)
+ goto out;
+
switch ( chn->state )
{
case ECS_VIRQ:
@@ -706,6 +754,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);
@@ -715,8 +765,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().
@@ -729,9 +784,10 @@ static long evtchn_unmask(evtchn_unmask_
vcpu_mark_events_pending(v);
}
+out:
spin_unlock(&d->evtchn_lock);
- return 0;
+ return ret;
}
@@ -740,6 +796,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;
@@ -749,6 +806,12 @@ 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);
@@ -940,10 +1003,18 @@ void notify_via_xen_event_channel(int lp
int evtchn_init(struct domain *d)
{
+ struct evtchn *chn;
+ int rc;
+
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;
+ rc = xsm_evtchn_init(d, chn);
+ if (rc)
+ return rc;
+
return 0;
}
@@ -958,8 +1029,10 @@ void evtchn_destroy(struct domain *d)
(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 8117f6684991 -r 68b27338e2e4 xen/common/grant_table.c
--- a/xen/common/grant_table.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/grant_table.c Wed Mar 7 18:30:23 2007 -0500
@@ -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);
@@ -442,6 +451,14 @@ __gnttab_unmap_grant_ref(
return;
}
+ rc = xsm_grant_unmapref(ld, rd);
+ if (rc)
+ {
+ rcu_unlock_domain(rd);
+ op->status = GNTST_permission_denied;
+ return;
+ }
+
TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
spin_lock(&rd->grant_table->lock);
@@ -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;
@@ -712,6 +737,13 @@ gnttab_query_size(
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;
+ }
+
spin_lock(&d->grant_table->lock);
op.nr_frames = nr_grant_frames(d->grant_table);
@@ -858,6 +890,13 @@ gnttab_transfer(
goto copyback;
}
+ if ( xsm_grant_transfer(d, e) )
+ {
+ rcu_unlock_domain(e);
+ gop.status = GNTST_permission_denied;
+ goto copyback;
+ }
+
spin_lock(&e->page_alloc_lock);
/*
@@ -1078,6 +1117,12 @@ __gnttab_copy(
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 )
{
rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame);
diff -r 8117f6684991 -r 68b27338e2e4 xen/common/kexec.c
--- a/xen/common/kexec.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/kexec.c Wed Mar 7 18:30:23 2007 -0500
@@ -20,6 +20,7 @@
#include <xen/spinlock.h>
#include <xen/version.h>
#include <public/elfnote.h>
+#include <xsm/xsm.h>
#ifndef COMPAT
@@ -355,6 +356,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 8117f6684991 -r 68b27338e2e4 xen/common/memory.c
--- a/xen/common/memory.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/memory.c Wed Mar 7 18:30:23 2007 -0500
@@ -22,6 +22,7 @@
#include <asm/current.h>
#include <asm/hardirq.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
struct memop_args {
/* INPUT */
@@ -269,6 +270,12 @@ static long translate_gpfn_list(
}
mfn = gmfn_to_mfn(d, gpfn);
+
+ if (xsm_translate_gpfn_list(current->domain, mfn))
+ {
+ rcu_unlock_domain(d);
+ return -EPERM;
+ }
if ( unlikely(__copy_to_guest_offset(op.mfn_list, i, &mfn, 1)) )
{
@@ -549,6 +556,13 @@ 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:
@@ -594,6 +608,13 @@ long do_memory_op(unsigned long cmd, XEN
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;
+ }
+
rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
if ( unlikely(domid != DOMID_SELF) )
diff -r 8117f6684991 -r 68b27338e2e4 xen/common/schedule.c
--- a/xen/common/schedule.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/schedule.c Wed Mar 7 18:30:23 2007 -0500
@@ -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";
@@ -434,6 +435,12 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
if ( d == NULL )
break;
+ ret = xsm_schedop_shutdown(current->domain, d);
+ if (ret) {
+ rcu_unlock_domain(d);
+ return ret;
+ }
+
domain_shutdown(d, (u8)sched_remote_shutdown.reason);
rcu_unlock_domain(d);
ret = 0;
diff -r 8117f6684991 -r 68b27338e2e4 xen/common/sysctl.c
--- a/xen/common/sysctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/sysctl.c Wed Mar 7 18:30:23 2007 -0500
@@ -20,6 +20,7 @@
#include <xen/guest_access.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);
@@ -45,6 +46,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,
@@ -56,6 +61,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;
@@ -64,6 +73,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
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,
@@ -95,7 +112,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
ret = -EFAULT;
break;
}
-
+
num_domains++;
}
@@ -114,6 +131,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 8117f6684991 -r 68b27338e2e4 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/xenoprof.c Wed Mar 7 18:30:23 2007 -0500
@@ -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
@@ -576,7 +577,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
current->domain->domain_id, op);
return -EPERM;
}
-
+ ret = xsm_profile(current->domain, op);
+ if (ret)
+ return ret;
+
spin_lock(&xenoprof_lock);
switch ( op )
diff -r 8117f6684991 -r 68b27338e2e4 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/drivers/char/console.c Wed Mar 7 18:30:23 2007 -0500
@@ -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;
@@ -349,6 +350,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 8117f6684991 -r 68b27338e2e4 xen/include/public/xen.h
--- a/xen/include/public/xen.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/public/xen.h Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/xen/hypercall.h Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/xen/sched.h Wed Mar 7 18:30:23 2007 -0500
@@ -62,6 +62,7 @@ struct evtchn
u16 pirq; /* state == ECS_PIRQ */
u16 virq; /* state == ECS_VIRQ */
} u;
+ void *ssid;
};
int evtchn_init(struct domain *d);
diff -r 8117f6684991 -r 68b27338e2e4 xen/include/xsm/xsm.h
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h Wed Mar 7 18:30:23 2007 -0500
@@ -0,0 +1,1033 @@
+/*
+ * 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);
+
+/* 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 (*createdomain) (struct xen_domctl *op);
+ void (*createdomain_post) (struct domain *d, struct xen_domctl *op);
+ void (*createdomain_fail) (struct xen_domctl *op);
+ 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 (*shadow_control) (struct domain *d, uint32_t op);
+ int (*xen_settime) (void);
+ 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 (*hypercall_init) (struct domain *d);
+ int (*hvmcontext) (struct domain *d, uint32_t op);
+ int (*address_size) (struct domain *d, uint32_t op);
+
+ 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);
+ 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_vcpu) (struct domain *d, struct evtchn *chn, unsigned int vcpu);
+ int (*evtchn_unmask) (struct domain *d, struct evtchn *chn);
+ int (*evtchn_reset) (struct domain *d1, struct domain *d2);
+ 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 (*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 (*mmu_normal_update) (struct domain *d, intpte_t fpte);
+ int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
+ 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 (*add_to_physmap) (struct domain *d1, struct domain *d2);
+ int (*machine_memory_map) (void);
+ int (*domain_memory_map) (struct domain *d1, struct domain *d);
+ int (*machphys_mfn_list) (struct domain *d);
+
+ int (*console_io) (struct domain *d, int cmd);
+
+ 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 (*profile) (struct domain *d, int 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 (*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);
+};
+
+extern struct xsm_operations *xsm_ops;
+
+static inline void xsm_security_domaininfo (struct domain *d,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return xsm_ops->resumedomain(d);
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return xsm_ops->createdomain(op);
+}
+
+static inline void xsm_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ xsm_ops->createdomain_post(d, op);
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *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_vcpuaffinity (int cmd, struct domain *d)
+{
+ return xsm_ops->vcpuaffinity(cmd, d);
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ return xsm_ops->scheduler(d);
+}
+
+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_domain_settime (struct domain *d)
+{
+ return xsm_ops->domain_settime(d);
+}
+
+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_perfcontrol (void)
+{
+ return xsm_ops->perfcontrol();
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return xsm_ops->shadow_control(d, op);
+}
+
+static inline int xsm_xen_settime (void)
+{
+ return xsm_ops->xen_settime();
+}
+
+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_hypercall_init (struct domain *d)
+{
+ return xsm_ops->hypercall_init(d);
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->hvmcontext(d, cmd);
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->address_size(d, cmd);
+}
+
+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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return xsm_ops->evtchn_close_post(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_reset (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->evtchn_reset(d1, d2);
+}
+
+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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_copy(d1, d2);
+}
+
+static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_query_size(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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->mmu_machphys_update(d, mfn);
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->translate_gpfn_list(d, mfn);
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return xsm_ops->memory_adjust_reservation(d1, d2);
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return xsm_ops->memory_stat_reservation(d1, d2);
+}
+
+static inline int xsm_memory_pin_page(struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->memory_pin_page(d, mfn);
+}
+
+static inline int xsm_update_va_mapping(struct domain *d, intpte_t pte)
+{
+ return xsm_ops->update_va_mapping(d, pte);
+}
+
+static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->add_to_physmap(d1, d2);
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return xsm_ops->machine_memory_map();
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->domain_memory_map(d1, d2);
+}
+
+static inline int xsm_machphys_mfn_list(struct domain *d)
+{
+ return xsm_ops->machphys_mfn_list(d);
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return xsm_ops->console_io(d, cmd);
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_unmask(d, pirq);
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_status(d, pirq);
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return xsm_ops->apic(d, cmd);
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return xsm_ops->assign_vector(d, pirq);
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return xsm_ops->profile(d, op);
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return xsm_ops->hvm_param(d, op);
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_intx_level(d);
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_isa_irq_level(d);
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_link_route(d);
+}
+
+static inline int xsm_kexec (void)
+{
+ return xsm_ops->kexec();
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->schedop_shutdown(d1, d2);
+}
+
+static inline long __do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return xsm_ops->__do_xsm_op(cmd, 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,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return 0;
+}
+
+static inline void xsm_createdomain_post (struct domain *d,
+ struct xen_domctl *op)
+{
+ return;
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_destroydomain (struct domain *d1)
+{
+ return 0;
+}
+
+static inline int xsm_vcpuaffinity (int cmd, struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ 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_domain_settime (struct domain *d)
+{
+ 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_perfcontrol (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return 0;
+}
+
+static inline int xsm_xen_settime (void)
+{
+ 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_hypercall_init (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return 0;
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ 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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return;
+}
+
+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_reset (struct domain *d1, struct domain *d2)
+{
+ 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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_grant_query_size (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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_pin_page (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_update_va_mapping (struct domain *d, intpte_t pte)
+{
+ return 0;
+}
+
+static inline int xsm_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return 0;
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machphys_mfn_list (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return 0;
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_kexec (void)
+{
+ return 0;
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline long __do_xsm_op (int cmd, XEN_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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op);
diff -r 8117f6684991 -r 68b27338e2e4 xen/xsm/Makefile
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/xsm/dummy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c Wed Mar 7 18:30:23 2007 -0500
@@ -0,0 +1,547 @@
+/*
+ * 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_createdomain(struct xen_domctl *op)
+{
+ return 0;
+}
+
+static void dummy_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ return;
+}
+
+static void dummy_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+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_shadow_control (struct domain *d, uint32_t op)
+{
+ 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_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_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_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_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_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_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_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ 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_console_io (struct domain *d, int cmd)
+{
+ 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_profile (struct domain *d, int op)
+{
+ 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_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 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 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_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(int cmd, XEN_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(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, 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, 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, shadow_control);
+ 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, 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, hypercall_init);
+ set_to_dummy_if_null(ops, hvmcontext);
+ set_to_dummy_if_null(ops, address_size);
+
+ 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_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_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, 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, mmu_normal_update);
+ set_to_dummy_if_null(ops, mmu_machphys_update);
+ 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, add_to_physmap);
+ set_to_dummy_if_null(ops, machine_memory_map);
+ set_to_dummy_if_null(ops, domain_memory_map);
+
+ set_to_dummy_if_null(ops, console_io);
+ 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, profile);
+
+ 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, 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);
+}
diff -r 8117f6684991 -r 68b27338e2e4 xen/xsm/xsm_core.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c Wed Mar 7 18:30:23 2007 -0500
@@ -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 8117f6684991 -r 68b27338e2e4 xen/xsm/xsm_policy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c Wed Mar 7 18:30:23 2007 -0500
@@ -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] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 15:28 [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch George S. Coker, II
@ 2007-03-08 15:59 ` Alex Williamson
2007-03-08 16:16 ` George S. Coker, II
2007-03-08 16:21 ` Keir Fraser
1 sibling, 1 reply; 17+ messages in thread
From: Alex Williamson @ 2007-03-08 15:59 UTC (permalink / raw)
To: George S. Coker, II; +Cc: xen-devel, xense-devel
On Thu, 2007-03-08 at 10:28 -0500, George S. Coker, II wrote:
> + /*
> + * 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
This is unacceptable, please make it fail gracefully on non-x86.
Thanks,
Alex
--
Alex Williamson HP Open Source & Linux Org.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 15:59 ` Alex Williamson
@ 2007-03-08 16:16 ` George S. Coker, II
2007-03-08 16:43 ` Alex Williamson
0 siblings, 1 reply; 17+ messages in thread
From: George S. Coker, II @ 2007-03-08 16:16 UTC (permalink / raw)
To: Alex Williamson; +Cc: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 955 bytes --]
On Thu, 2007-03-08 at 08:59 -0700, Alex Williamson wrote:
> On Thu, 2007-03-08 at 10:28 -0500, George S. Coker, II wrote:
> > + /*
> > + * 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
>
> This is unacceptable, please make it fail gracefully on non-x86.
Indeed, it looks like this logic is outdated. This was based on some
older code from ACM. The attached patch addresses this issue.
> Thanks,
>
> Alex
>
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
[-- Attachment #2: xsm-policy-init-030807.diff --]
[-- Type: text/x-patch, Size: 2052 bytes --]
diff -r 68b27338e2e4 -r 64a50f90db68 xen/xsm/xsm_policy.c
--- a/xen/xsm/xsm_policy.c Wed Mar 7 18:30:23 2007 -0500
+++ b/xen/xsm/xsm_policy.c Thu Mar 8 11:14:22 2007 -0500
@@ -31,46 +31,34 @@ int xsm_policy_init(unsigned int *initrd
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;
+ char *_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 *)(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
+ _policy_start = (char *)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
+ _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_buffer = _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;
- }
-
+ if ( i == 1 )
+ *initrdidx = (mbi->mods_count > 2) ? 2 : 0;
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] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 15:28 [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch George S. Coker, II
2007-03-08 15:59 ` Alex Williamson
@ 2007-03-08 16:21 ` Keir Fraser
2007-03-08 18:08 ` George S. Coker, II
1 sibling, 1 reply; 17+ messages in thread
From: Keir Fraser @ 2007-03-08 16:21 UTC (permalink / raw)
To: George S. Coker, II, xen-devel, xense-devel
On 8/3/07 15:28, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> The hooks implemented by this patch provide a framework for security
> modules to interpose and complement the existing privileged hypercall
> operationsin xen as well as interpose on the discretionary operations
> between domains.
I guess the primary question here is whether the set of hooks is reasonable.
The approach here seems to be comprehensive, to say the least.
For example, do we envisage policies where it is not only desirable to
interpose at event-channel binding time (particularly for interdomain
channels) but also on every send? Do you need to interpose on all types of
bindings? Interposing on interdomain bindings is obviously required, but
virq/pirq/ipi seem pretty dubious to me: virq/ipi bindings have only
local-domain scope, and protection of physical resources (like pirqs) is
already done via io capabilities.
Picking another example, is it useful to distinguish between the different
ways that a domain can act on the visible state of an HVM guest. For
example, you have hooks for setting pci link routes, and changing isa and
pci intx interrupt levels (as separate hooks!): it seems to me that some
more abstract capability could cover all these cases without loss of useful
generality.
As for the rest of the patches, I suspect they'll be largely okay. We should
refactor all the security code in Xen to sit under xen/security or xen/xsm.
In particular, flask/ and acm/ would be relocated under here. When you add
hook code to existing files, please format the code to that file's
conventions (which are typically not k&r or linux style!). The flask_op()
hypercall interface is rather opaque -- shouldn't you have a public header
file to define what that interface is? Having the command enumeration
directly above the hypercall implementation (and so private to Xen) seems
odd. And I'm not sure about the Plan9-style sscanf-of-strings interface
either. It should at least be documented. :-)
-- Keir
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 16:16 ` George S. Coker, II
@ 2007-03-08 16:43 ` Alex Williamson
0 siblings, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2007-03-08 16:43 UTC (permalink / raw)
To: George S. Coker, II; +Cc: xen-devel, xense-devel
On Thu, 2007-03-08 at 11:16 -0500, George S. Coker, II wrote:
> On Thu, 2007-03-08 at 08:59 -0700, Alex Williamson wrote:
> > On Thu, 2007-03-08 at 10:28 -0500, George S. Coker, II wrote:
> > > + /*
> > > + * 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
> >
> > This is unacceptable, please make it fail gracefully on non-x86.
>
> Indeed, it looks like this logic is outdated. This was based on some
> older code from ACM. The attached patch addresses this issue.
Thanks!
Alex
--
Alex Williamson HP Open Source & Linux Org.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 16:21 ` Keir Fraser
@ 2007-03-08 18:08 ` George S. Coker, II
2007-03-08 19:06 ` Keir Fraser
2007-03-08 19:08 ` George S. Coker, II
0 siblings, 2 replies; 17+ messages in thread
From: George S. Coker, II @ 2007-03-08 18:08 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, xense-devel
On Thu, 2007-03-08 at 16:21 +0000, Keir Fraser wrote:
> On 8/3/07 15:28, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
>
> > The hooks implemented by this patch provide a framework for security
> > modules to interpose and complement the existing privileged hypercall
> > operationsin xen as well as interpose on the discretionary operations
> > between domains.
>
> I guess the primary question here is whether the set of hooks is reasonable.
> The approach here seems to be comprehensive, to say the least.
>
> For example, do we envisage policies where it is not only desirable to
> interpose at event-channel binding time (particularly for interdomain
> channels) but also on every send?
The check on send, enables for the flask module the creation of a one-
way event channel. Flask can check whether A can send to B, but this
does not imply that B can send to A. The primary value for this check
is in the construction of one-way information flows.
> Do you need to interpose on all types of
> bindings? Interposing on interdomain bindings is obviously required, but
> virq/pirq/ipi seem pretty dubious to me: virq/ipi bindings have only
> local-domain scope, and protection of physical resources (like pirqs) is
> already done via io capabilities.
>
The pirq bindings are meant to protect the hypervisor against abuse by
the control-plane, thereby ensuring that the control-plane cannot setup
resource bindings that are prohibited by the policy. The control-plane
in this argument is decomposed or deprivileged by the running policy
such that it is unable to cause a policy reload and circumvent these
checks.
While the virq/ipi have local-domain scope, it is in the interest of
comprehensiveness that this hooks exists. For a domain running a
general purpose OS, this hook has little value since anything checked
here will always likely need to be granted. However, light-weight
domains for which the enforced policy could be justifiably more
restrictive, would benefit from this hook. I admit the value is
unproven for Xen today. ;)
> Picking another example, is it useful to distinguish between the different
> ways that a domain can act on the visible state of an HVM guest. For
> example, you have hooks for setting pci link routes, and changing isa and
> pci intx interrupt levels (as separate hooks!): it seems to me that some
> more abstract capability could cover all these cases without loss of useful
> generality.
>
Separate hooks does not necessarily mean separate permissions - the
breakdown of permissions is module dependent. Separate hooks allows for
a narrower per-hook interface (ensuring that the hooks are unlikely to
be abused for non-security purposes) and makes it unlikely that a given
hook will be separated from or lose context with the critical code path.
> As for the rest of the patches, I suspect they'll be largely okay. We should
> refactor all the security code in Xen to sit under xen/security or xen/xsm.
> In particular, flask/ and acm/ would be relocated under here. When you add
> hook code to existing files, please format the code to that file's
> conventions (which are typically not k&r or linux style!).
Yes.
> The flask_op()
> hypercall interface is rather opaque -- shouldn't you have a public header
> file to define what that interface is? Having the command enumeration
> directly above the hypercall implementation (and so private to Xen) seems
> odd. And I'm not sure about the Plan9-style sscanf-of-strings interface
> either. It should at least be documented. :-)
>
Fair enough. Up to this point, I've been trying to reduce the amount of
code deposited and made public across the Xen tree. It was not my
intention to hide the flask_op hypercall command structure.
Documentation will be forth coming after we straighten out any other
issues wrt XSM.
> -- Keir
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 18:08 ` George S. Coker, II
@ 2007-03-08 19:06 ` Keir Fraser
2007-03-08 19:58 ` George S. Coker, II
2007-03-08 19:08 ` George S. Coker, II
1 sibling, 1 reply; 17+ messages in thread
From: Keir Fraser @ 2007-03-08 19:06 UTC (permalink / raw)
To: George S. Coker, II, Keir Fraser; +Cc: xen-devel, xense-devel
On 8/3/07 18:08, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> The check on send, enables for the flask module the creation of a one-
> way event channel. Flask can check whether A can send to B, but this
> does not imply that B can send to A. The primary value for this check
> is in the construction of one-way information flows.
Fair enough.
> The pirq bindings are meant to protect the hypervisor against abuse by
> the control-plane, thereby ensuring that the control-plane cannot setup
> resource bindings that are prohibited by the policy. The control-plane
> in this argument is decomposed or deprivileged by the running policy
> such that it is unable to cause a policy reload and circumvent these
> checks.
You can restrict this via the iocaps mechanism, and I'll bet you already
include a hook that could prevent the domain from modifying its own iocaps
in a disallowed way. :-)
> While the virq/ipi have local-domain scope, it is in the interest of
> comprehensiveness that this hooks exists. For a domain running a
> general purpose OS, this hook has little value since anything checked
> here will always likely need to be granted. However, light-weight
> domains for which the enforced policy could be justifiably more
> restrictive, would benefit from this hook.
I don't think this is true. Same applies to evtchn_close(): another entirely
local VM operation. It seems outside the scope of XSM policy to be hooking
those. If you were to go this route then wouldn't you essentially be arguing
for interception of *every* hypercall subcommand?
> Separate hooks does not necessarily mean separate permissions - the
> breakdown of permissions is module dependent. Separate hooks allows for
> a narrower per-hook interface (ensuring that the hooks are unlikely to
> be abused for non-security purposes) and makes it unlikely that a given
> hook will be separated from or lose context with the critical code path.
If new critical code paths are added then XSM could end up with a set of
critical paths that it doesn't hook at all. That would be less of a problem
if the hooks aren't pushed way down into hypercall subcommands. I guess you
can argue this one either way. With this scheme you don't end up having to
demux the hypercall subcommands in every XSM module implementation.
-- Keir
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 18:08 ` George S. Coker, II
2007-03-08 19:06 ` Keir Fraser
@ 2007-03-08 19:08 ` George S. Coker, II
1 sibling, 0 replies; 17+ messages in thread
From: George S. Coker, II @ 2007-03-08 19:08 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 272 bytes --]
> When you add
> > hook code to existing files, please format the code to that file's
> > conventions (which are typically not k&r or linux style!).
>
Attached is an xsm patch updated for coding style.....
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
[-- Attachment #2: xsm-030807-xen-14282.diff --]
[-- Type: text/x-patch, Size: 91597 bytes --]
diff -r 8117f6684991 -r 091fc390e6f1 Config.mk
--- a/Config.mk Wed Mar 7 16:21:21 2007 +0000
+++ b/Config.mk Thu Mar 8 14:04:28 2007 -0500
@@ -56,6 +56,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 8117f6684991 -r 091fc390e6f1 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 Wed Mar 7 16:21:21 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 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 Wed Mar 7 16:21:21 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/Makefile
--- a/xen/Makefile Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/Makefile Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/Rules.mk
--- a/xen/Rules.mk Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/Rules.mk Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/domctl.c Thu Mar 8 14:04:28 2007 -0500
@@ -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);
@@ -166,6 +188,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)) )
@@ -225,6 +251,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);
@@ -264,6 +297,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;
@@ -298,6 +338,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) )
@@ -330,6 +374,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;
@@ -381,6 +429,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
@@ -407,6 +462,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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c Thu Mar 8 14:04:28 2007 -0500
@@ -1,3 +1,4 @@
+
/*
* hvm.c: Common hardware virtual machine abstractions.
*
@@ -715,6 +716,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;
@@ -758,6 +763,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;
@@ -800,6 +809,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) )
@@ -844,6 +857,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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/irq.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/mm.c Thu Mar 8 14:04:28 2007 -0500
@@ -109,6 +109,7 @@
#include <asm/e820.h>
#include <asm/hypercall.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -2017,6 +2018,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;
@@ -2295,6 +2300,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);
@@ -2386,6 +2395,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");
@@ -2720,6 +2733,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);
@@ -2976,6 +2993,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:
@@ -3052,6 +3076,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;
@@ -3085,9 +3117,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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/physdev.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/platform_hypercall.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/setup.c Thu Mar 8 14:04:28 2007 -0500
@@ -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();
@@ -737,6 +740,8 @@ void __init __start_xen(multiboot_info_t
/* Post-create hook 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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/sysctl.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/entry.S Thu Mar 8 14:04:28 2007 -0500
@@ -671,6 +671,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
@@ -714,6 +715,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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/mm.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_32/xen.lds.S Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/arch/x86/x86_64/entry.S Thu Mar 8 14:04:28 2007 -0500
@@ -587,6 +587,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
@@ -630,6 +631,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 8117f6684991 -r 091fc390e6f1 xen/common/domain.c
--- a/xen/common/domain.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/domain.c Thu Mar 8 14:04:28 2007 -0500
@@ -28,6 +28,7 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#include <xsm/xsm.h>
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
@@ -156,6 +157,9 @@ struct domain *domain_create(domid_t dom
d->is_hvm = 1;
rangeset_domain_initialise(d);
+
+ if ( xsm_alloc_security_domain(d) )
+ goto fail1;
if ( !is_idle_domain(d) )
{
@@ -357,6 +361,8 @@ static void complete_domain_destroy(stru
arch_domain_destroy(d);
+ xsm_free_security_domain(d);
+
free_domain(d);
send_guest_global_virq(dom0, VIRQ_DOM_EXC);
diff -r 8117f6684991 -r 091fc390e6f1 xen/common/domctl.c
--- a/xen/common/domctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/domctl.c Thu Mar 8 14:04:28 2007 -0500
@@ -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;
@@ -207,6 +210,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;
+ ret = xsm_setvcpucontext(d);
+ if ( ret )
+ goto svc_out;
+
ret = -EINVAL;
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
goto svc_out;
@@ -254,12 +261,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);
}
}
@@ -271,6 +283,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_unpausedomain(d);
+ if ( ret )
+ goto unpausedomain_out;
+
ret = -EINVAL;
if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
@@ -278,6 +294,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
domain_unpause_by_systemcontroller(d);
ret = 0;
}
+
+ unpausedomain_out:
rcu_unlock_domain(d);
}
}
@@ -291,10 +309,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_resumedomain(d);
+ if ( ret )
+ goto resumedomain_out;
+
ret = 0;
if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) )
for_each_vcpu ( d, v )
vcpu_wake(v);
+
+ resumedomain_out:
rcu_unlock_domain(d);
}
}
@@ -310,6 +334,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( supervisor_mode_kernel ||
(op->u.createdomain.flags & ~XEN_DOMCTL_CDF_hvm_guest) )
return -EINVAL;
+
+ ret = xsm_createdomain(op);
+ if ( ret )
+ goto createdomain_out;
dom = op->domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
@@ -343,12 +371,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = domain_create(dom, domcr_flags)) == NULL )
break;
+ xsm_createdomain_post(d, op);
+
ret = 0;
memcpy(d->handle, op->u.createdomain.handle,
sizeof(xen_domain_handle_t));
op->domain = d->domain_id;
+
+ createdomain_out:
+ if ( ret )
+ xsm_createdomain_fail(op);
+
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
}
@@ -365,6 +400,10 @@ 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 )
break;
/* Needed, for example, to ensure writable p.t. state is synced. */
@@ -403,12 +442,17 @@ 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);
}
}
@@ -426,6 +470,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;
@@ -460,10 +508,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;
@@ -492,12 +545,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;
@@ -511,6 +569,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 )
@@ -568,6 +633,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;
@@ -603,6 +672,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);
@@ -617,6 +690,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
spin_unlock(&d->page_alloc_lock);
+ max_mem_out:
rcu_unlock_domain(d);
}
break;
@@ -628,6 +702,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdomainhandle(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
rcu_unlock_domain(d);
@@ -643,6 +724,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdebugging(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
if ( op->u.setdebugging.enable )
set_bit(_DOMF_debugging, &d->domain_flags);
else
@@ -667,11 +755,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;
@@ -690,12 +783,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;
@@ -708,6 +806,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 8117f6684991 -r 091fc390e6f1 xen/common/event_channel.c
--- a/xen/common/event_channel.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/event_channel.c Thu Mar 8 14:04:28 2007 -0500
@@ -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,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;
@@ -261,6 +282,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;
@@ -295,6 +321,10 @@ static long evtchn_bind_pirq(evtchn_bind
ERROR_EXIT(port);
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,
@@ -342,6 +372,10 @@ static long __evtchn_close(struct domain
rc = -EINVAL;
goto out;
}
+
+ rc = xsm_evtchn_close(d1, chn1);
+ if ( rc )
+ goto out;
switch ( chn1->state )
{
@@ -427,6 +461,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 +506,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 +540,7 @@ long evtchn_send(unsigned int lport)
ret = -EINVAL;
}
+out:
spin_unlock(&ld->evtchn_lock);
return ret;
@@ -610,6 +651,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:
@@ -676,6 +722,10 @@ long evtchn_bind_vcpu(unsigned int port,
goto out;
}
+ rc = xsm_evtchn_vcpu(d, chn, vcpu_id);
+ if ( rc )
+ goto out;
+
switch ( chn->state )
{
case ECS_VIRQ:
@@ -706,6 +756,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);
@@ -715,7 +767,12 @@ 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
@@ -729,9 +786,10 @@ static long evtchn_unmask(evtchn_unmask_
vcpu_mark_events_pending(v);
}
+out:
spin_unlock(&d->evtchn_lock);
- return 0;
+ return ret;
}
@@ -740,6 +798,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;
@@ -749,6 +808,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);
@@ -940,10 +1006,19 @@ void notify_via_xen_event_channel(int lp
int evtchn_init(struct domain *d)
{
+ struct evtchn *chn;
+ int rc;
+
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;
+
+ rc = xsm_evtchn_init(d, chn);
+ if ( rc )
+ return rc;
+
return 0;
}
@@ -959,7 +1034,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 8117f6684991 -r 091fc390e6f1 xen/common/grant_table.c
--- a/xen/common/grant_table.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/grant_table.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/common/kexec.c
--- a/xen/common/kexec.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/kexec.c Thu Mar 8 14:04:28 2007 -0500
@@ -20,6 +20,7 @@
#include <xen/spinlock.h>
#include <xen/version.h>
#include <public/elfnote.h>
+#include <xsm/xsm.h>
#ifndef COMPAT
@@ -354,6 +355,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 )
{
diff -r 8117f6684991 -r 091fc390e6f1 xen/common/memory.c
--- a/xen/common/memory.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/memory.c Thu Mar 8 14:04:28 2007 -0500
@@ -22,6 +22,7 @@
#include <asm/current.h>
#include <asm/hardirq.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
struct memop_args {
/* INPUT */
@@ -227,6 +228,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;
@@ -269,6 +271,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)) )
{
@@ -549,6 +558,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:
@@ -593,6 +610,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;
+ }
rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
diff -r 8117f6684991 -r 091fc390e6f1 xen/common/schedule.c
--- a/xen/common/schedule.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/schedule.c Thu Mar 8 14:04:28 2007 -0500
@@ -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";
@@ -433,6 +434,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_shutdown(d, (u8)sched_remote_shutdown.reason);
rcu_unlock_domain(d);
diff -r 8117f6684991 -r 091fc390e6f1 xen/common/sysctl.c
--- a/xen/common/sysctl.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/sysctl.c Thu Mar 8 14:04:28 2007 -0500
@@ -20,6 +20,7 @@
#include <xen/guest_access.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);
@@ -45,6 +46,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,
@@ -56,6 +61,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;
@@ -64,6 +73,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
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,
@@ -95,7 +112,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
ret = -EFAULT;
break;
}
-
+
num_domains++;
}
@@ -114,6 +131,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 8117f6684991 -r 091fc390e6f1 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/common/xenoprof.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/drivers/char/console.c Thu Mar 8 14:04:28 2007 -0500
@@ -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;
@@ -349,6 +350,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 8117f6684991 -r 091fc390e6f1 xen/include/public/xen.h
--- a/xen/include/public/xen.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/public/xen.h Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/xen/hypercall.h Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Wed Mar 7 16:21:21 2007 +0000
+++ b/xen/include/xen/sched.h Thu Mar 8 14:04:28 2007 -0500
@@ -62,6 +62,7 @@ struct evtchn
u16 pirq; /* state == ECS_PIRQ */
u16 virq; /* state == ECS_VIRQ */
} u;
+ void *ssid;
};
int evtchn_init(struct domain *d);
diff -r 8117f6684991 -r 091fc390e6f1 xen/include/xsm/xsm.h
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h Thu Mar 8 14:04:28 2007 -0500
@@ -0,0 +1,1033 @@
+/*
+ * 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);
+
+/* 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 (*createdomain) (struct xen_domctl *op);
+ void (*createdomain_post) (struct domain *d, struct xen_domctl *op);
+ void (*createdomain_fail) (struct xen_domctl *op);
+ 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 (*shadow_control) (struct domain *d, uint32_t op);
+ int (*xen_settime) (void);
+ 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 (*hypercall_init) (struct domain *d);
+ int (*hvmcontext) (struct domain *d, uint32_t op);
+ int (*address_size) (struct domain *d, uint32_t op);
+
+ 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);
+ 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_vcpu) (struct domain *d, struct evtchn *chn, unsigned int vcpu);
+ int (*evtchn_unmask) (struct domain *d, struct evtchn *chn);
+ int (*evtchn_reset) (struct domain *d1, struct domain *d2);
+ 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 (*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 (*mmu_normal_update) (struct domain *d, intpte_t fpte);
+ int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
+ 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 (*add_to_physmap) (struct domain *d1, struct domain *d2);
+ int (*machine_memory_map) (void);
+ int (*domain_memory_map) (struct domain *d1, struct domain *d);
+ int (*machphys_mfn_list) (struct domain *d);
+
+ int (*console_io) (struct domain *d, int cmd);
+
+ 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 (*profile) (struct domain *d, int 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 (*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);
+};
+
+extern struct xsm_operations *xsm_ops;
+
+static inline void xsm_security_domaininfo (struct domain *d,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return xsm_ops->resumedomain(d);
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return xsm_ops->createdomain(op);
+}
+
+static inline void xsm_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ xsm_ops->createdomain_post(d, op);
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *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_vcpuaffinity (int cmd, struct domain *d)
+{
+ return xsm_ops->vcpuaffinity(cmd, d);
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ return xsm_ops->scheduler(d);
+}
+
+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_domain_settime (struct domain *d)
+{
+ return xsm_ops->domain_settime(d);
+}
+
+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_perfcontrol (void)
+{
+ return xsm_ops->perfcontrol();
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return xsm_ops->shadow_control(d, op);
+}
+
+static inline int xsm_xen_settime (void)
+{
+ return xsm_ops->xen_settime();
+}
+
+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_hypercall_init (struct domain *d)
+{
+ return xsm_ops->hypercall_init(d);
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->hvmcontext(d, cmd);
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->address_size(d, cmd);
+}
+
+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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return xsm_ops->evtchn_close_post(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_reset (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->evtchn_reset(d1, d2);
+}
+
+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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_copy(d1, d2);
+}
+
+static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_query_size(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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->mmu_machphys_update(d, mfn);
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->translate_gpfn_list(d, mfn);
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return xsm_ops->memory_adjust_reservation(d1, d2);
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return xsm_ops->memory_stat_reservation(d1, d2);
+}
+
+static inline int xsm_memory_pin_page(struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->memory_pin_page(d, mfn);
+}
+
+static inline int xsm_update_va_mapping(struct domain *d, intpte_t pte)
+{
+ return xsm_ops->update_va_mapping(d, pte);
+}
+
+static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->add_to_physmap(d1, d2);
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return xsm_ops->machine_memory_map();
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->domain_memory_map(d1, d2);
+}
+
+static inline int xsm_machphys_mfn_list(struct domain *d)
+{
+ return xsm_ops->machphys_mfn_list(d);
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return xsm_ops->console_io(d, cmd);
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_unmask(d, pirq);
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_status(d, pirq);
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return xsm_ops->apic(d, cmd);
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return xsm_ops->assign_vector(d, pirq);
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return xsm_ops->profile(d, op);
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return xsm_ops->hvm_param(d, op);
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_intx_level(d);
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_isa_irq_level(d);
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_link_route(d);
+}
+
+static inline int xsm_kexec (void)
+{
+ return xsm_ops->kexec();
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->schedop_shutdown(d1, d2);
+}
+
+static inline long __do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return xsm_ops->__do_xsm_op(cmd, 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,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return 0;
+}
+
+static inline void xsm_createdomain_post (struct domain *d,
+ struct xen_domctl *op)
+{
+ return;
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_destroydomain (struct domain *d1)
+{
+ return 0;
+}
+
+static inline int xsm_vcpuaffinity (int cmd, struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ 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_domain_settime (struct domain *d)
+{
+ 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_perfcontrol (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return 0;
+}
+
+static inline int xsm_xen_settime (void)
+{
+ 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_hypercall_init (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return 0;
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ 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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return;
+}
+
+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_reset (struct domain *d1, struct domain *d2)
+{
+ 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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_grant_query_size (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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_pin_page (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_update_va_mapping (struct domain *d, intpte_t pte)
+{
+ return 0;
+}
+
+static inline int xsm_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return 0;
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machphys_mfn_list (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return 0;
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_kexec (void)
+{
+ return 0;
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline long __do_xsm_op (int cmd, XEN_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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op);
diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/Makefile
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/xsm/dummy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c Thu Mar 8 14:04:28 2007 -0500
@@ -0,0 +1,547 @@
+/*
+ * 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_createdomain(struct xen_domctl *op)
+{
+ return 0;
+}
+
+static void dummy_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ return;
+}
+
+static void dummy_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+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_shadow_control (struct domain *d, uint32_t op)
+{
+ 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_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_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_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_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_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_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_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ 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_console_io (struct domain *d, int cmd)
+{
+ 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_profile (struct domain *d, int op)
+{
+ 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_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 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 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_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(int cmd, XEN_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(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, 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, 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, shadow_control);
+ 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, 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, hypercall_init);
+ set_to_dummy_if_null(ops, hvmcontext);
+ set_to_dummy_if_null(ops, address_size);
+
+ 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_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_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, 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, mmu_normal_update);
+ set_to_dummy_if_null(ops, mmu_machphys_update);
+ 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, add_to_physmap);
+ set_to_dummy_if_null(ops, machine_memory_map);
+ set_to_dummy_if_null(ops, domain_memory_map);
+
+ set_to_dummy_if_null(ops, console_io);
+ 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, profile);
+
+ 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, 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);
+}
diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/xsm_core.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c Thu Mar 8 14:04:28 2007 -0500
@@ -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 8117f6684991 -r 091fc390e6f1 xen/xsm/xsm_policy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c Thu Mar 8 14:04:28 2007 -0500
@@ -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;
+ char *_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 = (char *)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 = _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] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 19:06 ` Keir Fraser
@ 2007-03-08 19:58 ` George S. Coker, II
2007-03-09 9:43 ` Keir Fraser
0 siblings, 1 reply; 17+ messages in thread
From: George S. Coker, II @ 2007-03-08 19:58 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, xense-devel
> > The pirq bindings are meant to protect the hypervisor against abuse by
> > the control-plane, thereby ensuring that the control-plane cannot setup
> > resource bindings that are prohibited by the policy. The control-plane
> > in this argument is decomposed or deprivileged by the running policy
> > such that it is unable to cause a policy reload and circumvent these
> > checks.
>
> You can restrict this via the iocaps mechanism, and I'll bet you already
> include a hook that could prevent the domain from modifying its own iocaps
> in a disallowed way. :-)
>
Right, while we do check the iocaps setup, there is more value here than
a simple check on bind. XSM has also introduced a security field for
event channels. The value of this security field can only practically
be computed at bind time, so whether a security module wants to do a
permission check on binding for pirq/virq/ipi is not as relevant as
whether the module needs to assign a security field to the channel. The
purpose of the security field is not only to facilitate information
flows to resources, virtual or physical, in the hypervisor, but also to
facilitate guests in the ability to identify channels based on these
security properties and support information flows mediated by these
guests. This is really an important property for creating secure
channels between domains as well as other resources (virtual or
physical) resources.
> > While the virq/ipi have local-domain scope, it is in the interest of
> > comprehensiveness that this hooks exists. For a domain running a
> > general purpose OS, this hook has little value since anything checked
> > here will always likely need to be granted. However, light-weight
> > domains for which the enforced policy could be justifiably more
> > restrictive, would benefit from this hook.
>
> I don't think this is true. Same applies to evtchn_close(): another entirely
> local VM operation. It seems outside the scope of XSM policy to be hooking
> those. If you were to go this route then wouldn't you essentially be arguing
> for interception of *every* hypercall subcommand?
>
I certainly do not want to go down the path of intercepting *every*
hypercall subcommand. Let me give a bit more detail about what kinds of
capabilities that I am suggesting. To achieve a very light-weight
domain, one would like to remove as much functionality from that domain
as possible, to include the interrupt handler. Instead, there would
exist a light-weight domain interrupt handler domain that is responsible
for this functionality. These interrupts would manifest as interdomain
channels; however, the ipi mechanism remains unless a hook exists to
block this code path. Likewise, the light-weight domains wouldn't be
able to close their channels arbitrarily, and require a check on close
as well.
> > Separate hooks does not necessarily mean separate permissions - the
> > breakdown of permissions is module dependent. Separate hooks allows for
> > a narrower per-hook interface (ensuring that the hooks are unlikely to
> > be abused for non-security purposes) and makes it unlikely that a given
> > hook will be separated from or lose context with the critical code path.
>
> If new critical code paths are added then XSM could end up with a set of
> critical paths that it doesn't hook at all. That would be less of a problem
> if the hooks aren't pushed way down into hypercall subcommands. I guess you
> can argue this one either way. With this scheme you don't end up having to
> demux the hypercall subcommands in every XSM module implementation.
It does go either way, but hopefully, as XSM becomes part of Xen, new
hooks or the need for new hooks won't be as opaque as it is in the roll-
up implementation. At least in the current XSM, it is clear as to what
is/not checked. Another issue is demuxing in the hook forces a wide
hook interface - not to mention needless hook processing on every entry
to the hypercall. Demuxing in the hook also makes the hook and the rest
of Xen ripe for abuse ala typical ioctl style issues.
George
>
> -- Keir
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-08 19:58 ` George S. Coker, II
@ 2007-03-09 9:43 ` Keir Fraser
2007-03-09 16:55 ` George S. Coker, II
0 siblings, 1 reply; 17+ messages in thread
From: Keir Fraser @ 2007-03-09 9:43 UTC (permalink / raw)
To: George S. Coker, II, Keir Fraser; +Cc: xen-devel, xense-devel
On 8/3/07 19:58, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> purpose of the security field is not only to facilitate information
> flows to resources, virtual or physical, in the hypervisor, but also to
> facilitate guests in the ability to identify channels based on these
> security properties and support information flows mediated by these
> guests. This is really an important property for creating secure
> channels between domains as well as other resources (virtual or
> physical) resources.
E.g., the information flow from timer events to a guest? I can't envisage
what kinds of policies you might have in mind. I'm probably missing some
bigger picture.
> To achieve a very light-weight
> domain, one would like to remove as much functionality from that domain
> as possible, to include the interrupt handler. Instead, there would
> exist a light-weight domain interrupt handler domain that is responsible
> for this functionality. These interrupts would manifest as interdomain
> channels; however, the ipi mechanism remains unless a hook exists to
> block this code path. Likewise, the light-weight domains wouldn't be
> able to close their channels arbitrarily, and require a check on close
> as well.
I think this sounds like a microkernel-style 'interrupt server'? Why would
you want that? And if you did have it, why would you care about the clients
of this server closing their ends of interdomain event channels?
-- Keir
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 9:43 ` Keir Fraser
@ 2007-03-09 16:55 ` George S. Coker, II
2007-03-09 17:51 ` Stefan Berger
0 siblings, 1 reply; 17+ messages in thread
From: George S. Coker, II @ 2007-03-09 16:55 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, xense-devel
On Fri, 2007-03-09 at 09:43 +0000, Keir Fraser wrote:
> On 8/3/07 19:58, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
>
> > purpose of the security field is not only to facilitate information
> > flows to resources, virtual or physical, in the hypervisor, but also to
> > facilitate guests in the ability to identify channels based on these
> > security properties and support information flows mediated by these
> > guests. This is really an important property for creating secure
> > channels between domains as well as other resources (virtual or
> > physical) resources.
>
> E.g., the information flow from timer events to a guest? I can't envisage
> what kinds of policies you might have in mind. I'm probably missing some
> bigger picture.
>
Perhaps, but I think that for now, it is hard to prove value for the
hooks covering virq, ipi, and pirq, so they should be ommitted.
> > To achieve a very light-weight
> > domain, one would like to remove as much functionality from that domain
> > as possible, to include the interrupt handler. Instead, there would
> > exist a light-weight domain interrupt handler domain that is responsible
> > for this functionality. These interrupts would manifest as interdomain
> > channels; however, the ipi mechanism remains unless a hook exists to
> > block this code path. Likewise, the light-weight domains wouldn't be
> > able to close their channels arbitrarily, and require a check on close
> > as well.
>
> I think this sounds like a microkernel-style 'interrupt server'? Why would
> you want that? And if you did have it, why would you care about the clients
> of this server closing their ends of interdomain event channels?
>
Fair enough. I'll remove the close check, although we will still need a
hook in the close code path for cleanup.
> -- Keir
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 16:55 ` George S. Coker, II
@ 2007-03-09 17:51 ` Stefan Berger
2007-03-09 20:04 ` George S. Coker, II
0 siblings, 1 reply; 17+ messages in thread
From: Stefan Berger @ 2007-03-09 17:51 UTC (permalink / raw)
To: George S. Coker, II
Cc: xen-devel, Keir Fraser, xense-devel, xen-devel-bounces
[-- Attachment #1.1: Type: text/plain, Size: 1670 bytes --]
xen-devel-bounces@lists.xensource.com wrote on 03/09/2007 11:55:11 AM:
> On Fri, 2007-03-09 at 09:43 +0000, Keir Fraser wrote:
> > On 8/3/07 19:58, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> >
>
> > > To achieve a very light-weight
> > > domain, one would like to remove as much functionality from that
domain
> > > as possible, to include the interrupt handler. Instead, there would
> > > exist a light-weight domain interrupt handler domain that is
responsible
> > > for this functionality. These interrupts would manifest as
interdomain
> > > channels; however, the ipi mechanism remains unless a hook exists to
> > > block this code path. Likewise, the light-weight domains wouldn't
be
> > > able to close their channels arbitrarily, and require a check on
close
> > > as well.
> >
> > I think this sounds like a microkernel-style 'interrupt server'? Why
would
> > you want that? And if you did have it, why would you care about the
clients
> > of this server closing their ends of interdomain event channels?
> >
> Fair enough. I'll remove the close check, although we will still need a
> hook in the close code path for cleanup.
>
There's also a mediation in evtchn_init() [.evtchn_init]. evtchn_init() is
called from one since place only and that is domain_create(), which in
turn is behind the xsm_createdomain() mediation call [.createdomain]. I
suppose it would be enough to guard the creation of a domain by the
xsm_createdomain() hook only, no?
Stefan
> > -- Keir
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 2137 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] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 17:51 ` Stefan Berger
@ 2007-03-09 20:04 ` George S. Coker, II
2007-03-09 22:01 ` Stefan Berger
0 siblings, 1 reply; 17+ messages in thread
From: George S. Coker, II @ 2007-03-09 20:04 UTC (permalink / raw)
To: Stefan Berger; +Cc: xen-devel, Keir Fraser, xense-devel, xen-devel-bounces
On Fri, 2007-03-09 at 12:51 -0500, Stefan Berger wrote:
>
> xen-devel-bounces@lists.xensource.com wrote on 03/09/2007 11:55:11 AM:
>
> > On Fri, 2007-03-09 at 09:43 +0000, Keir Fraser wrote:
> > > On 8/3/07 19:58, "George S. Coker, II" <gscoker@alpha.ncsc.mil>
> wrote:
> > >
> >
> > > > To achieve a very light-weight
> > > > domain, one would like to remove as much functionality from that
> domain
> > > > as possible, to include the interrupt handler. Instead, there
> would
> > > > exist a light-weight domain interrupt handler domain that is
> responsible
> > > > for this functionality. These interrupts would manifest as
> interdomain
> > > > channels; however, the ipi mechanism remains unless a hook
> exists to
> > > > block this code path. Likewise, the light-weight domains
> wouldn't be
> > > > able to close their channels arbitrarily, and require a check on
> close
> > > > as well.
> > >
> > > I think this sounds like a microkernel-style 'interrupt server'?
> Why would
> > > you want that? And if you did have it, why would you care about
> the clients
> > > of this server closing their ends of interdomain event channels?
> > >
> > Fair enough. I'll remove the close check, although we will still
> need a
> > hook in the close code path for cleanup.
> >
>
> There's also a mediation in evtchn_init() [.evtchn_init]. evtchn_init
> () is called from one since place only and that is domain_create(),
> which in turn is behind the xsm_createdomain() mediation call
> [.createdomain]. I suppose it would be enough to guard the creation of
> a domain by the xsm_createdomain() hook only, no?
>
In light of the other comments, you are correct.
> Stefan
>
>
> > > -- Keir
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xensource.com
> > http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 20:04 ` George S. Coker, II
@ 2007-03-09 22:01 ` Stefan Berger
2007-03-09 22:07 ` George S. Coker, II
2007-03-09 22:09 ` Keir Fraser
0 siblings, 2 replies; 17+ messages in thread
From: Stefan Berger @ 2007-03-09 22:01 UTC (permalink / raw)
To: George S. Coker, II
Cc: xen-devel, Keir Fraser, xense-devel, xen-devel-bounces
[-- Attachment #1.1: Type: text/plain, Size: 2461 bytes --]
xen-devel-bounces@lists.xensource.com wrote on 03/09/2007 03:04:56 PM:
> On Fri, 2007-03-09 at 12:51 -0500, Stefan Berger wrote:
> >
> > xen-devel-bounces@lists.xensource.com wrote on 03/09/2007 11:55:11 AM:
> >
> > > On Fri, 2007-03-09 at 09:43 +0000, Keir Fraser wrote:
> > > > On 8/3/07 19:58, "George S. Coker, II" <gscoker@alpha.ncsc.mil>
> > wrote:
> > > >
> > >
> > > > > To achieve a very light-weight
> > > > > domain, one would like to remove as much functionality from that
> > domain
> > > > > as possible, to include the interrupt handler. Instead, there
> > would
> > > > > exist a light-weight domain interrupt handler domain that is
> > responsible
> > > > > for this functionality. These interrupts would manifest as
> > interdomain
> > > > > channels; however, the ipi mechanism remains unless a hook
> > exists to
> > > > > block this code path. Likewise, the light-weight domains
> > wouldn't be
> > > > > able to close their channels arbitrarily, and require a check on
> > close
> > > > > as well.
> > > >
> > > > I think this sounds like a microkernel-style 'interrupt server'?
> > Why would
> > > > you want that? And if you did have it, why would you care about
> > the clients
> > > > of this server closing their ends of interdomain event channels?
> > > >
> > > Fair enough. I'll remove the close check, although we will still
> > need a
> > > hook in the close code path for cleanup.
> > >
> >
> > There's also a mediation in evtchn_init() [.evtchn_init]. evtchn_init
> > () is called from one since place only and that is domain_create(),
> > which in turn is behind the xsm_createdomain() mediation call
> > [.createdomain]. I suppose it would be enough to guard the creation of
> > a domain by the xsm_createdomain() hook only, no?
> >
> In light of the other comments, you are correct.
Why is there mediation in evtchn_reset [.evtchn_reset]? It looks like the
code tries to only close an event channel if necessary. I suppose that
once you have been allowed to open an event channel you should be able to
reset (close) it.
Stefan
>
> > Stefan
> >
> >
> > > > -- Keir
> > >
> > >
> > > _______________________________________________
> > > Xen-devel mailing list
> > > Xen-devel@lists.xensource.com
> > > http://lists.xensource.com/xen-devel
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 3419 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] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 22:01 ` Stefan Berger
@ 2007-03-09 22:07 ` George S. Coker, II
2007-03-09 22:09 ` Keir Fraser
1 sibling, 0 replies; 17+ messages in thread
From: George S. Coker, II @ 2007-03-09 22:07 UTC (permalink / raw)
To: Stefan Berger; +Cc: xen-devel, Keir Fraser, xense-devel, xen-devel-bounces
> Why is there mediation in evtchn_reset [.evtchn_reset]? It looks like
> the code tries to only close an event channel if necessary. I suppose
> that once you have been allowed to open an event channel you should be
> able to reset (close) it.
>
To deprivilege the hypercall, because it can be called by an
unprivileged domain on itself and by a privileged domain on another
domain.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
2007-03-09 22:01 ` Stefan Berger
2007-03-09 22:07 ` George S. Coker, II
@ 2007-03-09 22:09 ` Keir Fraser
1 sibling, 0 replies; 17+ messages in thread
From: Keir Fraser @ 2007-03-09 22:09 UTC (permalink / raw)
To: Stefan Berger, George S. Coker, II
Cc: xen-devel, xense-devel, xen-devel-bounces
[-- Attachment #1.1: Type: text/plain, Size: 1081 bytes --]
It¹s a bit different from close because it can act cross-domain. It doesn¹t
necessarily act on the caller.
K.
On 9/3/07 22:01, "Stefan Berger" <stefanb@us.ibm.com> wrote:
>
>
> Why is there mediation in evtchn_reset [.evtchn_reset]? It looks like the code
> tries to only close an event channel if necessary. I suppose that once you
> have been allowed to open an event channel you should be able to reset (close)
> it.
>
> Stefan
>
>> >
>>> > > Stefan
>>> > >
>>> > >
>>>>> > > > > -- Keir
>>>> > > >
>>>> > > >
>>>> > > > _______________________________________________
>>>> > > > Xen-devel mailing list
>>>> > > > Xen-devel@lists.xensource.com
>>>> > > > http://lists.xensource.com/xen-devel
>> >
>> >
>> > _______________________________________________
>> > Xen-devel mailing list
>> > Xen-devel@lists.xensource.com
>> > http://lists.xensource.com/xen-devel
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 2302 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] 17+ messages in thread
* [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch
@ 2007-03-13 19:33 George S. Coker, II
0 siblings, 0 replies; 17+ messages in thread
From: George S. Coker, II @ 2007-03-13 19:33 UTC (permalink / raw)
To: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 242 bytes --]
Updates in this patch set include:
- security module code managed under xsm/
- removal of local event channel hooks
- cleanup of xsm_policy.c
- style cleanups of hook code
Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>
[-- Attachment #2: xsm-031307-xen-14364.diff --]
[-- Type: text/x-patch, Size: 86931 bytes --]
diff -r 127bee61972b -r 8699ae65d2c8 Config.mk
--- a/Config.mk Tue Mar 13 14:56:03 2007 +0000
+++ b/Config.mk Tue Mar 13 15:08:33 2007 -0400
@@ -56,6 +56,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 127bee61972b -r 8699ae65d2c8 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 Tue Mar 13 14:56:03 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 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 Tue Mar 13 14:56:03 2007 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/Makefile
--- a/xen/Makefile Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/Makefile Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/Rules.mk
--- a/xen/Rules.mk Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/Rules.mk Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/domctl.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c Tue Mar 13 15:08:33 2007 -0400
@@ -1,3 +1,4 @@
+
/*
* hvm.c: Common hardware virtual machine abstractions.
*
@@ -761,6 +762,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;
@@ -804,6 +809,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;
@@ -846,6 +855,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) )
@@ -890,6 +903,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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/irq.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/mm.c Tue Mar 13 15:08:33 2007 -0400
@@ -109,6 +109,7 @@
#include <asm/e820.h>
#include <asm/hypercall.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -2020,6 +2021,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;
@@ -2298,6 +2303,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);
@@ -2389,6 +2398,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");
@@ -2723,6 +2736,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);
@@ -2979,6 +2996,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:
@@ -3055,6 +3079,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;
@@ -3088,9 +3120,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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/physdev.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/platform_hypercall.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/setup.c Tue Mar 13 15:08:33 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();
@@ -735,6 +738,8 @@ void __init __start_xen(multiboot_info_t
/* Post-create hook 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/sysctl.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/x86_32/entry.S Tue Mar 13 15:08:33 2007 -0400
@@ -671,6 +671,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
@@ -714,6 +715,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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/x86_32/mm.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/x86_32/xen.lds.S Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/arch/x86/x86_64/entry.S Tue Mar 13 15:08:33 2007 -0400
@@ -587,6 +587,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
@@ -630,6 +631,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 127bee61972b -r 8699ae65d2c8 xen/common/domain.c
--- a/xen/common/domain.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/domain.c Tue Mar 13 15:08:33 2007 -0400
@@ -28,6 +28,7 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#include <xsm/xsm.h>
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
@@ -156,6 +157,9 @@ struct domain *domain_create(domid_t dom
d->is_hvm = 1;
rangeset_domain_initialise(d);
+
+ if ( xsm_alloc_security_domain(d) )
+ goto fail1;
if ( !is_idle_domain(d) )
{
@@ -360,6 +364,8 @@ static void complete_domain_destroy(stru
arch_domain_destroy(d);
+ xsm_free_security_domain(d);
+
free_domain(d);
send_guest_global_virq(dom0, VIRQ_DOM_EXC);
diff -r 127bee61972b -r 8699ae65d2c8 xen/common/domctl.c
--- a/xen/common/domctl.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/domctl.c Tue Mar 13 15:08:33 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;
@@ -207,6 +210,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;
@@ -254,12 +264,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);
}
}
@@ -273,7 +288,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;
}
@@ -287,10 +308,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_resumedomain(d);
+ if ( ret )
+ goto resumedomain_out;
+
ret = 0;
if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) )
for_each_vcpu ( d, v )
vcpu_wake(v);
+
+ resumedomain_out:
rcu_unlock_domain(d);
}
}
@@ -306,6 +333,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( supervisor_mode_kernel ||
(op->u.createdomain.flags & ~XEN_DOMCTL_CDF_hvm_guest) )
return -EINVAL;
+
+ ret = xsm_createdomain(op);
+ if ( ret )
+ goto createdomain_out;
dom = op->domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
@@ -339,12 +370,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = domain_create(dom, domcr_flags)) == NULL )
break;
+ xsm_createdomain_post(d, op);
+
ret = 0;
memcpy(d->handle, op->u.createdomain.handle,
sizeof(xen_domain_handle_t));
op->domain = d->domain_id;
+
+ createdomain_out:
+ if ( ret )
+ xsm_createdomain_fail(op);
+
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
}
@@ -362,6 +400,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);
@@ -399,12 +444,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);
}
}
@@ -422,6 +473,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;
@@ -456,10 +511,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;
@@ -488,12 +548,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;
@@ -507,6 +572,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 )
@@ -564,6 +637,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;
@@ -599,6 +676,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);
@@ -613,6 +694,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
spin_unlock(&d->page_alloc_lock);
+ max_mem_out:
rcu_unlock_domain(d);
}
break;
@@ -624,6 +706,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdomainhandle(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
rcu_unlock_domain(d);
@@ -639,6 +728,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdebugging(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
if ( op->u.setdebugging.enable )
set_bit(_DOMF_debugging, &d->domain_flags);
else
@@ -663,11 +759,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;
@@ -686,12 +787,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;
@@ -704,6 +810,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 127bee61972b -r 8699ae65d2c8 xen/common/event_channel.c
--- a/xen/common/event_channel.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/event_channel.c Tue Mar 13 15:08:33 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;
@@ -613,6 +638,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:
@@ -709,6 +739,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);
@@ -718,7 +750,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
@@ -734,7 +767,7 @@ static long evtchn_unmask(evtchn_unmask_
spin_unlock(&d->evtchn_lock);
- return 0;
+ return ret;
}
@@ -743,6 +776,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;
@@ -752,6 +786,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);
@@ -943,10 +984,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;
}
@@ -962,7 +1007,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 127bee61972b -r 8699ae65d2c8 xen/common/grant_table.c
--- a/xen/common/grant_table.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/grant_table.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/common/kexec.c
--- a/xen/common/kexec.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/kexec.c Tue Mar 13 15:08:33 2007 -0400
@@ -20,6 +20,7 @@
#include <xen/spinlock.h>
#include <xen/version.h>
#include <public/elfnote.h>
+#include <xsm/xsm.h>
#ifndef COMPAT
@@ -354,6 +355,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 )
{
diff -r 127bee61972b -r 8699ae65d2c8 xen/common/memory.c
--- a/xen/common/memory.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/memory.c Tue Mar 13 15:08:33 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 */
@@ -227,6 +228,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;
@@ -269,6 +271,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)) )
{
@@ -549,6 +558,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:
@@ -593,6 +610,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;
+ }
rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
diff -r 127bee61972b -r 8699ae65d2c8 xen/common/schedule.c
--- a/xen/common/schedule.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/schedule.c Tue Mar 13 15:08:33 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";
@@ -454,6 +455,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_shutdown(d, (u8)sched_remote_shutdown.reason);
rcu_unlock_domain(d);
diff -r 127bee61972b -r 8699ae65d2c8 xen/common/sysctl.c
--- a/xen/common/sysctl.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/sysctl.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/common/xenoprof.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/drivers/char/console.c Tue Mar 13 15:08:33 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;
@@ -349,6 +350,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 127bee61972b -r 8699ae65d2c8 xen/include/public/xen.h
--- a/xen/include/public/xen.h Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/include/public/xen.h Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/include/xen/hypercall.h Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Tue Mar 13 14:56:03 2007 +0000
+++ b/xen/include/xen/sched.h Tue Mar 13 15:08:33 2007 -0400
@@ -62,6 +62,7 @@ struct evtchn
u16 pirq; /* state == ECS_PIRQ */
u16 virq; /* state == ECS_VIRQ */
} u;
+ void *ssid;
};
int evtchn_init(struct domain *d);
diff -r 127bee61972b -r 8699ae65d2c8 xen/include/xsm/xsm.h
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h Tue Mar 13 15:08:33 2007 -0400
@@ -0,0 +1,951 @@
+/*
+ * 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);
+
+/* 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 (*createdomain) (struct xen_domctl *op);
+ void (*createdomain_post) (struct domain *d, struct xen_domctl *op);
+ void (*createdomain_fail) (struct xen_domctl *op);
+ 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 (*shadow_control) (struct domain *d, uint32_t op);
+ int (*xen_settime) (void);
+ 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 (*hypercall_init) (struct domain *d);
+ int (*hvmcontext) (struct domain *d, uint32_t op);
+ int (*address_size) (struct domain *d, uint32_t op);
+
+ 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 (*mmu_normal_update) (struct domain *d, intpte_t fpte);
+ int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
+ 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 (*add_to_physmap) (struct domain *d1, struct domain *d2);
+ int (*machine_memory_map) (void);
+ int (*domain_memory_map) (struct domain *d1, struct domain *d);
+ int (*machphys_mfn_list) (struct domain *d);
+
+ int (*console_io) (struct domain *d, int cmd);
+
+ 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 (*profile) (struct domain *d, int 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 (*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);
+};
+
+extern struct xsm_operations *xsm_ops;
+
+static inline void xsm_security_domaininfo (struct domain *d,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return xsm_ops->resumedomain(d);
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return xsm_ops->createdomain(op);
+}
+
+static inline void xsm_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ xsm_ops->createdomain_post(d, op);
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *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_vcpuaffinity (int cmd, struct domain *d)
+{
+ return xsm_ops->vcpuaffinity(cmd, d);
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ return xsm_ops->scheduler(d);
+}
+
+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_domain_settime (struct domain *d)
+{
+ return xsm_ops->domain_settime(d);
+}
+
+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_perfcontrol (void)
+{
+ return xsm_ops->perfcontrol();
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return xsm_ops->shadow_control(d, op);
+}
+
+static inline int xsm_xen_settime (void)
+{
+ return xsm_ops->xen_settime();
+}
+
+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_hypercall_init (struct domain *d)
+{
+ return xsm_ops->hypercall_init(d);
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->hvmcontext(d, cmd);
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ return xsm_ops->address_size(d, cmd);
+}
+
+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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return xsm_ops->evtchn_close_post(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_reset (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->evtchn_reset(d1, d2);
+}
+
+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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_copy(d1, d2);
+}
+
+static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->grant_query_size(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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->mmu_machphys_update(d, mfn);
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->translate_gpfn_list(d, mfn);
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return xsm_ops->memory_adjust_reservation(d1, d2);
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return xsm_ops->memory_stat_reservation(d1, d2);
+}
+
+static inline int xsm_memory_pin_page(struct domain *d, unsigned long mfn)
+{
+ return xsm_ops->memory_pin_page(d, mfn);
+}
+
+static inline int xsm_update_va_mapping(struct domain *d, intpte_t pte)
+{
+ return xsm_ops->update_va_mapping(d, pte);
+}
+
+static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->add_to_physmap(d1, d2);
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return xsm_ops->machine_memory_map();
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->domain_memory_map(d1, d2);
+}
+
+static inline int xsm_machphys_mfn_list(struct domain *d)
+{
+ return xsm_ops->machphys_mfn_list(d);
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return xsm_ops->console_io(d, cmd);
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_unmask(d, pirq);
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return xsm_ops->pirq_status(d, pirq);
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return xsm_ops->apic(d, cmd);
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return xsm_ops->assign_vector(d, pirq);
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return xsm_ops->profile(d, op);
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return xsm_ops->hvm_param(d, op);
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_intx_level(d);
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return xsm_ops->hvm_set_isa_irq_level(d);
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return xsm_ops->hvm_set_pci_link_route(d);
+}
+
+static inline int xsm_kexec (void)
+{
+ return xsm_ops->kexec();
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return xsm_ops->schedop_shutdown(d1, d2);
+}
+
+static inline long __do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return xsm_ops->__do_xsm_op(cmd, 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,
+ struct xen_domctl_getdomaininfo *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_resumedomain (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_createdomain (struct xen_domctl *op)
+{
+ return 0;
+}
+
+static inline void xsm_createdomain_post (struct domain *d,
+ struct xen_domctl *op)
+{
+ return;
+}
+
+static inline void xsm_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_destroydomain (struct domain *d1)
+{
+ return 0;
+}
+
+static inline int xsm_vcpuaffinity (int cmd, struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ 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_domain_settime (struct domain *d)
+{
+ 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_perfcontrol (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return 0;
+}
+
+static inline int xsm_xen_settime (void)
+{
+ 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_hypercall_init (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return 0;
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ 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 void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ return;
+}
+
+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_reset (struct domain *d1, struct domain *d2)
+{
+ 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_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_grant_query_size (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 int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_memory_pin_page (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static inline int xsm_update_va_mapping (struct domain *d, intpte_t pte)
+{
+ return 0;
+}
+
+static inline int xsm_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return 0;
+}
+
+static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline int xsm_machphys_mfn_list (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_unmask (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_pirq_status (struct domain *d, int pirq)
+{
+ return 0;
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return 0;
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return 0;
+}
+
+static inline int xsm_kexec (void)
+{
+ return 0;
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static inline long __do_xsm_op (int cmd, XEN_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 (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op);
diff -r 127bee61972b -r 8699ae65d2c8 xen/xsm/Makefile
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/xsm/dummy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c Tue Mar 13 15:08:33 2007 -0400
@@ -0,0 +1,509 @@
+/*
+ * 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_createdomain(struct xen_domctl *op)
+{
+ return 0;
+}
+
+static void dummy_createdomain_post (struct domain *d, struct xen_domctl *op)
+{
+ return;
+}
+
+static void dummy_createdomain_fail (struct xen_domctl *op)
+{
+ return;
+}
+
+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_shadow_control (struct domain *d, uint32_t op)
+{
+ 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_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_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_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_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_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_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_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ 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_console_io (struct domain *d, int cmd)
+{
+ 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_profile (struct domain *d, int op)
+{
+ 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_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;
+}
+
+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, 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, 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, shadow_control);
+ 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, 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, hypercall_init);
+ set_to_dummy_if_null(ops, hvmcontext);
+ set_to_dummy_if_null(ops, address_size);
+
+ 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, mmu_normal_update);
+ set_to_dummy_if_null(ops, mmu_machphys_update);
+ 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, add_to_physmap);
+ set_to_dummy_if_null(ops, machine_memory_map);
+ set_to_dummy_if_null(ops, domain_memory_map);
+
+ set_to_dummy_if_null(ops, console_io);
+ 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, profile);
+
+ 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, 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);
+}
diff -r 127bee61972b -r 8699ae65d2c8 xen/xsm/xsm_core.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c Tue Mar 13 15:08:33 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 127bee61972b -r 8699ae65d2c8 xen/xsm/xsm_policy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c Tue Mar 13 15:08:33 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] 17+ messages in thread
end of thread, other threads:[~2007-03-13 19:33 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-08 15:28 [Xense-devel][PATCH][XSM][1/4] Xen Security Modules Patch George S. Coker, II
2007-03-08 15:59 ` Alex Williamson
2007-03-08 16:16 ` George S. Coker, II
2007-03-08 16:43 ` Alex Williamson
2007-03-08 16:21 ` Keir Fraser
2007-03-08 18:08 ` George S. Coker, II
2007-03-08 19:06 ` Keir Fraser
2007-03-08 19:58 ` George S. Coker, II
2007-03-09 9:43 ` Keir Fraser
2007-03-09 16:55 ` George S. Coker, II
2007-03-09 17:51 ` Stefan Berger
2007-03-09 20:04 ` George S. Coker, II
2007-03-09 22:01 ` Stefan Berger
2007-03-09 22:07 ` George S. Coker, II
2007-03-09 22:09 ` Keir Fraser
2007-03-08 19:08 ` George S. Coker, II
-- strict thread matches above, loose matches on Subject: below --
2007-03-13 19:33 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.