* [Xense-devel] [PATCH] [1/4] XSM Framework
@ 2006-12-20 14:08 George S. Coker, II
2006-12-20 15:11 ` Stefan Berger
2006-12-21 10:53 ` Keir Fraser
0 siblings, 2 replies; 10+ messages in thread
From: George S. Coker, II @ 2006-12-20 14:08 UTC (permalink / raw)
To: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 2017 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 operations
in 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-121906-xen-unstable.diff --]
[-- Type: text/x-patch, Size: 83802 bytes --]
diff -r 37141c3a3d39 -r 65bfdf932c7e Config.mk
--- a/Config.mk Mon Dec 11 15:06:53 2006 +0000
+++ b/Config.mk Sat Dec 16 11:53:48 2006 -0500
@@ -51,6 +51,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 37141c3a3d39 -r 65bfdf932c7e 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 Mon Dec 11 15:06:53 2006 +0000
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Sat Dec 16 11:53:48 2006 -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 37141c3a3d39 -r 65bfdf932c7e 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 Mon Dec 11 15:06:53 2006 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Sat Dec 16 11:53:48 2006 -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 37141c3a3d39 -r 65bfdf932c7e xen/Makefile
--- a/xen/Makefile Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/Makefile Sat Dec 16 11:53:48 2006 -0500
@@ -45,6 +45,7 @@ _clean: delete-unfresh-files
$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
rm -f include/asm *.o $(TARGET)* *~ core
rm -f include/asm-*/asm-offsets.h
@@ -121,7 +122,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
echo ""; \
echo "#endif") <$< >$@
-SUBDIRS = acm arch/$(TARGET_ARCH) common drivers
+SUBDIRS = xsm acm arch/$(TARGET_ARCH) common drivers
define all_sources
( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
find include -name 'asm-*' -prune -o -name '*.h' -print; \
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/Rules.mk
--- a/xen/Rules.mk Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/Rules.mk Sat Dec 16 11:53:48 2006 -0500
@@ -46,10 +46,12 @@ HDRS := $(subst $(BASEDIR)/include/xen/c
# Note that link order matters!
ALL_OBJS-y += $(BASEDIR)/common/built_in.o
ALL_OBJS-y += $(BASEDIR)/drivers/built_in.o
+ALL_OBJS-y += $(BASEDIR)/xsm/built_in.o
ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
ALL_OBJS-y += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
CFLAGS-y += -g -D__XEN__
+CFLAGS-$(XSM_ENABLE) += -DXSM_ENABLE
CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY
CFLAGS-$(verbose) += -DVERBOSE
CFLAGS-$(crash_debug) += -DCRASH_DEBUG
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/domctl.c Sat Dec 16 11:53:48 2006 -0500
@@ -23,6 +23,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,
@@ -40,6 +41,12 @@ long arch_do_domctl(
d = find_domain_by_id(domctl->domain);
if ( d != NULL )
{
+ ret = xsm_shadow_control(d, domctl->u.shadow_op.op);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl);
put_domain(d);
copy_to_guest(u_domctl, domctl, 1);
@@ -60,6 +67,12 @@ long arch_do_domctl(
ret = -ESRCH;
if ( unlikely((d = find_domain_by_id(domctl->domain)) == NULL) )
break;
+
+ ret = xsm_ioport_permission(d, fp, domctl->u.ioport_permission.allow_access);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
if ( np == 0 )
ret = 0;
@@ -85,6 +98,12 @@ long arch_do_domctl(
unlikely((d = find_domain_by_id(dom)) == NULL) )
break;
+ ret = xsm_getpageframeinfo(mfn);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
page = mfn_to_page(mfn);
if ( likely(get_page(page, d)) )
@@ -160,6 +179,10 @@ long arch_do_domctl(
{
struct page_info *page;
unsigned long mfn = l_arr[j];
+
+ ret = xsm_getpageframeinfo(mfn);
+ if (ret)
+ continue;
page = mfn_to_page(mfn);
@@ -220,6 +243,12 @@ long arch_do_domctl(
ret = -EINVAL;
if ( d != NULL )
{
+ ret = xsm_getmemlist(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
ret = 0;
spin_lock(&d->page_alloc_lock);
@@ -258,6 +287,12 @@ long arch_do_domctl(
ret = -ESRCH;
if ( unlikely(d == NULL) )
break;
+
+ ret = xsm_hypercall_init(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
mfn = gmfn_to_mfn(d, gmfn);
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/hvm/hvm.c Sat Dec 16 11:53:48 2006 -0500
@@ -625,6 +625,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;
@@ -668,6 +672,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;
@@ -711,6 +719,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;
@@ -761,6 +773,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
return -EPERM;
}
+ rc = xsm_hvm_param(op, d);
+ if (rc)
+ goto param_fail;
+
rc = -EINVAL;
if ( !is_hvm_domain(d) )
goto param_fail;
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/irq.c Sat Dec 16 11:53:48 2006 -0500
@@ -15,6 +15,7 @@
#include <xen/keyhandler.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;
@@ -332,6 +333,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], s->evtchn_mask) )
__pirq_guest_eoi(d, irq);
}
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/mm.c Sat Dec 16 11:53:48 2006 -0500
@@ -107,6 +107,7 @@
#include <asm/x86_emulate.h>
#include <asm/e820.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
@@ -1947,6 +1948,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;
@@ -2217,6 +2222,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);
@@ -2318,6 +2327,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");
@@ -2651,6 +2664,10 @@ int do_update_va_mapping(unsigned long v
if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
return -EINVAL;
+ rc = xsm_update_va_mapping(current->domain, val64);
+ if (rc)
+ return rc;
+
LOCK_BIGLOCK(d);
pl1e = guest_map_l1e(v, va, &gl1mfn);
@@ -2908,6 +2925,11 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = find_domain_by_id(xatp.domid)) == NULL )
return -ESRCH;
+ if (xsm_add_to_physmap(current->domain, d)) {
+ put_domain(d);
+ return -EPERM;
+ }
+
switch ( xatp.space )
{
case XENMAPSPACE_shared_info:
@@ -2979,6 +3001,12 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = find_domain_by_id(fmap.domid)) == NULL )
return -ESRCH;
+ rc = xsm_domain_memory_map(d);
+ if (rc) {
+ put_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;
@@ -3012,10 +3040,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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/physdev.c Sat Dec 16 11:53:48 2006 -0500
@@ -11,6 +11,7 @@
#include <asm/smpboot.h>
#include <public/xen.h>
#include <public/physdev.h>
+#include <xsm/xsm.h>
int
ioapic_guest_read(
@@ -31,6 +32,9 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
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;
}
@@ -50,6 +54,9 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
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;
@@ -67,6 +74,9 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
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;
@@ -80,6 +90,9 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
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;
@@ -96,8 +109,12 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/platform_hypercall.c Sat Dec 16 11:53:48 2006 -0500
@@ -22,6 +22,7 @@
#include <public/platform.h>
#include <asm/mtrr.h>
#include "cpu/mtrr/mtrr.h"
+#include <xsm/xsm.h>
long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
{
@@ -44,6 +45,10 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
{
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);
@@ -53,6 +58,10 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
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,
@@ -71,6 +80,10 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
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)
@@ -90,6 +103,10 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
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 )
{
@@ -105,6 +122,11 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
case XENPF_microcode_update:
{
extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
+
+ ret = xsm_microcode();
+ if (ret)
+ break;
+
ret = microcode_update(op->u.microcode.data,
op->u.microcode.length);
}
@@ -114,6 +136,11 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
{
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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/setup.c Sat Dec 16 11:53:48 2006 -0500
@@ -28,6 +28,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);
@@ -626,6 +627,8 @@ void __init __start_xen(multiboot_info_t
percpu_init_areas();
+ xsm_init(&initrdidx, mbi, initial_images_start);
+
init_idle_domain();
trap_init();
@@ -703,6 +706,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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/sysctl.c Sat Dec 16 11:53:48 2006 -0500
@@ -24,6 +24,7 @@
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/processor.h>
+#include <xsm/xsm.h>
long arch_do_sysctl(
struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
@@ -37,6 +38,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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/x86_32/entry.S Sat Dec 16 11:53:48 2006 -0500
@@ -668,6 +668,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
@@ -711,6 +712,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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/x86_32/mm.c Sat Dec 16 11:53:48 2006 -0500
@@ -198,6 +198,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 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/x86_32/xen.lds.S Sat Dec 16 11:53:48 2006 -0500
@@ -60,6 +60,7 @@ SECTIONS
__initcall_start = .;
.initcall.init : { *(.initcall.init) } :text
__initcall_end = .;
+ .xsm_initcall.init : { __xsm_initcall_start = .; *(.xsm_initcall.init) __xsm_initcall_end = .; }
. = ALIGN(PAGE_SIZE);
__init_end = .;
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/arch/x86/x86_64/entry.S Sat Dec 16 11:53:48 2006 -0500
@@ -566,6 +566,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
@@ -609,6 +610,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 37141c3a3d39 -r 65bfdf932c7e xen/common/domain.c
--- a/xen/common/domain.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/domain.c Sat Dec 16 11:53:48 2006 -0500
@@ -26,6 +26,7 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#include <xsm/xsm.h>
/* Both these structures are protected by the domlist_lock. */
DEFINE_RWLOCK(domlist_lock);
@@ -147,6 +148,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) )
{
@@ -341,6 +345,8 @@ void domain_destroy(struct domain *d)
arch_domain_destroy(d);
+ xsm_free_security_domain(d);
+
free_domain(d);
send_guest_global_virq(dom0, VIRQ_DOM_EXC);
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/common/domctl.c
--- a/xen/common/domctl.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/domctl.c Sat Dec 16 11:53:48 2006 -0500
@@ -21,6 +21,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);
@@ -123,6 +124,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;
@@ -199,6 +202,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_setvcpucontext(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
ret = set_info_guest(d, &op->u.vcpucontext);
put_domain(d);
}
@@ -211,6 +219,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_pausedomain(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
ret = -EINVAL;
if ( d != current->domain )
{
@@ -228,6 +241,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_unpausedomain(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
ret = -EINVAL;
if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
@@ -251,6 +269,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
(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) )
{
@@ -283,12 +305,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = domain_create(dom, domcr_flags)) == NULL )
break;
+ xsm_createdomain_post(d, op);
+
memcpy(d->handle, op->u.createdomain.handle,
sizeof(xen_domain_handle_t));
ret = 0;
op->domain = d->domain_id;
+ createdomain_out:
+ if (ret)
+ xsm_createdomain_fail(op);
+
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
}
@@ -307,6 +335,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = find_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. */
domain_pause(d);
@@ -343,6 +375,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_destroydomain(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
ret = -EINVAL;
if ( d != current->domain )
{
@@ -366,6 +403,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;
+ ret = xsm_vcpuaffinity(op->cmd, d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
ret = -EINVAL;
if ( op->u.vcpuaffinity.vcpu >= MAX_VIRT_CPUS )
goto vcpuaffinity_out;
@@ -400,6 +443,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = find_domain_by_id(op->domain)) == NULL )
break;
+ ret = xsm_scheduler(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
ret = sched_adjust(d, &op->u.scheduler_op);
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
@@ -433,6 +482,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
read_unlock(&domlist_lock);
+
+ ret = xsm_getdomaininfo(d);
+ if (ret)
+ break;
getdomaininfo(d, &op->u.getdomaininfo);
@@ -454,6 +507,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = find_domain_by_id(op->domain)) == NULL )
break;
+ ret = xsm_getvcpucontext(d);
+ if (ret)
+ goto getvcpucontext_out;
+
ret = -EINVAL;
if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
goto getvcpucontext_out;
@@ -501,6 +558,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( (d = find_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 )
@@ -537,6 +598,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;
+ ret = xsm_setdomainmaxmem(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
ret = -EINVAL;
new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10);
@@ -559,6 +626,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = find_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdomainhandle(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
put_domain(d);
@@ -574,6 +646,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = find_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_setdebugging(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
if ( op->u.setdebugging.enable )
set_bit(_DOMF_debugging, &d->domain_flags);
else
@@ -598,6 +676,12 @@ 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) {
+ put_domain(d);
+ break;
+ }
+
if ( op->u.irq_permission.allow_access )
ret = irq_permit_access(d, pirq);
else
@@ -622,6 +706,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;
+ ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
+
if ( op->u.iomem_permission.allow_access )
ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
else
@@ -639,6 +729,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = find_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_domain_settime(d);
+ if (ret) {
+ put_domain(d);
+ break;
+ }
d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
put_domain(d);
ret = 0;
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/common/event_channel.c
--- a/xen/common/event_channel.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/event_channel.c Sat Dec 16 11:53:48 2006 -0500
@@ -29,6 +29,7 @@
#include <public/xen.h>
#include <public/event_channel.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>
#define bucket_from_port(d,p) \
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
@@ -88,9 +89,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;
}
@@ -119,6 +126,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 +187,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;
@@ -230,6 +245,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;
@@ -260,6 +280,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 +320,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));
@@ -341,7 +370,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:
@@ -425,6 +458,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 )
@@ -469,6 +503,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 )
{
@@ -499,6 +537,7 @@ long evtchn_send(unsigned int lport)
ret = -EINVAL;
}
+out:
spin_unlock(&ld->evtchn_lock);
return ret;
@@ -609,6 +648,11 @@ static long evtchn_status(evtchn_status_
}
chn = evtchn_from_port(d, port);
+
+ rc = xsm_evtchn_status(d, chn);
+ if (rc)
+ goto out;
+
switch ( chn->state )
{
case ECS_FREE:
@@ -675,6 +719,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:
@@ -705,6 +753,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);
@@ -714,8 +764,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().
@@ -728,9 +783,10 @@ static long evtchn_unmask(evtchn_unmask_
vcpu_mark_events_pending(v);
}
+out:
spin_unlock(&d->evtchn_lock);
- return 0;
+ return ret;
}
@@ -908,10 +964,16 @@ 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;
+ if (xsm_evtchn_init(d, chn))
+ return -EACCES;
+
return 0;
}
@@ -926,8 +988,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 37141c3a3d39 -r 65bfdf932c7e xen/common/grant_table.c
--- a/xen/common/grant_table.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/grant_table.c Sat Dec 16 11:53:48 2006 -0500
@@ -34,6 +34,7 @@
#include <xen/guest_access.h>
#include <xen/domain_page.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>
/*
* The first two members of a grant entry are updated as a combined pair.
@@ -132,6 +133,14 @@ __gnttab_map_grant_ref(
return;
}
+ rc = xsm_grant_mapref(ld, rd, op->flags);
+ if (rc)
+ {
+ put_domain(rd);
+ op->status = GNTST_permission_denied;
+ return;
+ }
+
/* Get a maptrack handle. */
if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
{
@@ -377,6 +386,14 @@ __gnttab_unmap_grant_ref(
return;
}
+ rc = xsm_grant_unmapref(ld, rd);
+ if (rc)
+ {
+ put_domain(rd);
+ op->status = GNTST_permission_denied;
+ return;
+ }
+
TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
act = &rd->grant_table->active[ref];
@@ -523,6 +540,13 @@ gnttab_setup_table(
goto out;
}
+ if ( xsm_grant_setup(current->domain, d) )
+ {
+ put_domain(d);
+ op.status = GNTST_permission_denied;
+ goto out;
+ }
+
ASSERT(d->grant_table != NULL);
op.status = GNTST_okay;
for ( i = 0; i < op.nr_frames; i++ )
@@ -663,6 +687,12 @@ gnttab_transfer(
goto copyback;
}
+ if ( xsm_grant_transfer(d, e) )
+ {
+ gop.status = GNTST_permission_denied;
+ goto copyback;
+ }
+
spin_lock(&e->page_alloc_lock);
/*
@@ -883,6 +913,12 @@ __gnttab_copy(
"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 37141c3a3d39 -r 65bfdf932c7e xen/common/kexec.c
--- a/xen/common/kexec.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/kexec.c Sat Dec 16 11:53:48 2006 -0500
@@ -21,6 +21,7 @@
#include <xen/spinlock.h>
#include <xen/version.h>
#include <public/elfnote.h>
+#include <xsm/xsm.h>
DEFINE_PER_CPU (crash_note_t, crash_notes);
cpumask_t crash_saved_cpus;
@@ -310,6 +311,10 @@ long do_kexec_op(unsigned long op, XEN_G
if ( !IS_PRIV(current->domain) )
return -EPERM;
+ ret = xsm_kexec();
+ if (ret)
+ return ret;
+
switch ( op )
{
case KEXEC_CMD_kexec_get_range:
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/common/memory.c
--- a/xen/common/memory.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/memory.c Sat Dec 16 11:53:48 2006 -0500
@@ -21,6 +21,7 @@
#include <asm/current.h>
#include <asm/hardirq.h>
#include <public/memory.h>
+#include <xsm/xsm.h>
/*
* To allow safe resume of do_memory_op() after preemption, we need to know
@@ -273,6 +274,12 @@ static long translate_gpfn_list(
}
mfn = gmfn_to_mfn(d, gpfn);
+
+ if (xsm_translate_gpfn_list(current->domain, mfn))
+ {
+ put_domain(d);
+ return -EPERM;
+ }
if ( unlikely(__copy_to_guest_offset(op.mfn_list, i, &mfn, 1)) )
{
@@ -553,6 +560,12 @@ long do_memory_op(unsigned long cmd, XEN
return start_extent;
args.domain = d;
+ rc = xsm_memory_adjust_reservation(current->domain, d);
+ if (rc) {
+ put_domain(d);
+ return rc;
+ }
+
switch ( op )
{
case XENMEM_increase_reservation:
@@ -598,6 +611,13 @@ long do_memory_op(unsigned long cmd, XEN
else if ( (d = find_domain_by_id(domid)) == NULL )
return -ESRCH;
+ rc = xsm_memory_stat_reservation(current->domain, d);
+ if (rc) {
+ if (domid != DOMID_SELF)
+ put_domain(d);
+ return rc;
+ }
+
rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
if ( unlikely(domid != DOMID_SELF) )
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/common/sysctl.c
--- a/xen/common/sysctl.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/sysctl.c Sat Dec 16 11:53:48 2006 -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);
@@ -47,6 +48,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,
@@ -58,6 +63,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;
@@ -66,6 +75,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;
@@ -92,6 +105,12 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
{
ret = -ESRCH;
break;
+ }
+
+ ret = xsm_getdomaininfo(d);
+ if (ret) {
+ put_domain(d);
+ continue;
}
getdomaininfo(d, &info);
@@ -124,6 +143,11 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
case XEN_SYSCTL_perfc_op:
{
extern int perfc_control(xen_sysctl_perfc_op_t *);
+
+ 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 37141c3a3d39 -r 65bfdf932c7e xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/common/xenoprof.c Sat Dec 16 11:53:48 2006 -0500
@@ -13,6 +13,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
@@ -562,7 +563,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 37141c3a3d39 -r 65bfdf932c7e xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/drivers/char/console.c Sat Dec 16 11:53:48 2006 -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;
@@ -342,6 +343,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 37141c3a3d39 -r 65bfdf932c7e xen/include/public/xen.h
--- a/xen/include/public/xen.h Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/include/public/xen.h Sat Dec 16 11:53:48 2006 -0500
@@ -82,6 +82,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 37141c3a3d39 -r 65bfdf932c7e xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/include/xen/hypercall.h Sat Dec 16 11:53:48 2006 -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(
@@ -108,4 +109,9 @@ do_kexec_op(
int arg1,
XEN_GUEST_HANDLE(void) arg);
+extern long
+do_xsm_op(
+ int cmd,
+ XEN_GUEST_HANDLE(xsm_op_t) u_xsm_op);
+
#endif /* __XEN_HYPERCALL_H__ */
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon Dec 11 15:06:53 2006 +0000
+++ b/xen/include/xen/sched.h Sat Dec 16 11:53:48 2006 -0500
@@ -50,6 +50,7 @@ struct evtchn
u16 pirq; /* state == ECS_PIRQ */
u16 virq; /* state == ECS_VIRQ */
} u;
+ void *ssid;
};
int evtchn_init(struct domain *d);
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/include/xsm/xsm.h
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h Sat Dec 16 11:53:48 2006 -0500
@@ -0,0 +1,966 @@
+/*
+ * 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 (*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 (*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_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 (*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 val);
+ int (*add_to_physmap) (struct domain *d1, struct domain *d2);
+ int (*machine_memory_map) (void);
+ int (*domain_memory_map) (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) (unsigned long op, struct domain *d);
+ 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);
+
+ 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_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_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_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_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 val)
+{
+ return xsm_ops->update_va_mapping(d, val);
+}
+
+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 *d)
+{
+ return xsm_ops->domain_memory_map(d);
+}
+
+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 (unsigned long op, struct domain *d)
+{
+ return xsm_ops->hvm_param(op, d);
+}
+
+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 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_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_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_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_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 val)
+{
+ 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 *d)
+{
+ 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 (unsigned long op, struct domain *d)
+{
+ 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 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 37141c3a3d39 -r 65bfdf932c7e xen/xsm/Makefile
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile Sat Dec 16 11:53:48 2006 -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 37141c3a3d39 -r 65bfdf932c7e xen/xsm/dummy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c Sat Dec 16 11:53:48 2006 -0500
@@ -0,0 +1,517 @@
+/*
+ * 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_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_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_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 val)
+{
+ 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 *d)
+{
+ 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 (unsigned long op, struct domain *d)
+{
+ 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_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, 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, 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, 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, __do_xsm_op);
+ set_to_dummy_if_null(ops, complete_init);
+}
diff -r 37141c3a3d39 -r 65bfdf932c7e xen/xsm/xsm_core.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c Sat Dec 16 11:53:48 2006 -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 37141c3a3d39 -r 65bfdf932c7e xen/xsm/xsm_policy.c
--- /dev/null Thu Jan 1 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c Sat Dec 16 11:53:48 2006 -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] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 14:08 [Xense-devel] [PATCH] [1/4] XSM Framework George S. Coker, II
@ 2006-12-20 15:11 ` Stefan Berger
2006-12-20 16:42 ` George S. Coker, II
2006-12-21 10:53 ` Keir Fraser
1 sibling, 1 reply; 10+ messages in thread
From: Stefan Berger @ 2006-12-20 15:11 UTC (permalink / raw)
To: George S. Coker, II; +Cc: xense-devel-bounces, xen-devel, xense-devel
[-- Attachment #1.1: Type: text/plain, Size: 2814 bytes --]
Hello George,
what's the to-be-expected side-effect if a hook like this is enforced (rc
!= 0)?
@@ -2217,6 +2222,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);
Stefan
xense-devel-bounces@lists.xensource.com wrote on 12/20/2006 09:08:40 AM:
> 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 operations
> in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> Berger/Watson/IBM] _______________________________________________
> Xense-devel mailing list
> Xense-devel@lists.xensource.com
> http://lists.xensource.com/xense-devel
[-- Attachment #1.2: Type: text/html, Size: 4124 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] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 15:11 ` Stefan Berger
@ 2006-12-20 16:42 ` George S. Coker, II
2006-12-20 17:39 ` Stefan Berger
0 siblings, 1 reply; 10+ messages in thread
From: George S. Coker, II @ 2006-12-20 16:42 UTC (permalink / raw)
To: Stefan Berger; +Cc: xense-devel-bounces, xen-devel, xense-devel
It should just be a fault, but I see that EPERM might not be blindly
interpreted as EFAULT.
On Wed, 2006-12-20 at 10:11 -0500, Stefan Berger wrote:
>
> Hello George,
>
> what's the to-be-expected side-effect if a hook like this is enforced
> (rc != 0)?
>
> @@ -2217,6 +2222,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);
>
>
> Stefan
>
> xense-devel-bounces@lists.xensource.com wrote on 12/20/2006 09:08:40
> AM:
>
> > 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
> operations
> > in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> > Berger/Watson/IBM] _______________________________________________
> > Xense-devel mailing list
> > Xense-devel@lists.xensource.com
> > http://lists.xensource.com/xense-devel
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 16:42 ` George S. Coker, II
@ 2006-12-20 17:39 ` Stefan Berger
2006-12-20 18:02 ` George S. Coker, II
0 siblings, 1 reply; 10+ messages in thread
From: Stefan Berger @ 2006-12-20 17:39 UTC (permalink / raw)
To: George S. Coker, II
Cc: xense-devel-bounces, xen-devel, xense-devel, xen-devel-bounces
[-- Attachment #1.1: Type: text/plain, Size: 4643 bytes --]
George,
i tried to simulate this hook by deactivating the MMU_NORMAL_PT_UPDATE
like this:
diff -r f80f1cc7f85e xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Dec 20 09:48:21 2006 +0000
+++ b/xen/arch/x86/mm.c Wed Dec 20 12:30:39 2006 -0500
@@ -2217,6 +2217,9 @@ int do_mmu_update(
*/
case MMU_NORMAL_PT_UPDATE:
+ if (!IS_PRIV(current->domain))
+ goto out;
+
gmfn = req.ptr >> PAGE_SHIFT;
mfn = gmfn_to_mfn(d, gmfn);
Domain-0 starts up fine. When trying to start a guest domain, the effect
on the application level was that an 'xm create <vmconfig file>' threw no
error, but the domain never appeared in the domain list - I suppose it
dies.
Otherwise, I saw you have two hooks for pause / unpause of a domain. I
wonder whether this should not rather be only one hook 'pausing' that
allows one to pause / unpause or disallows both operations, or why would
someone be allow to pause a domain and not unpause it later?
Stefan
xen-devel-bounces@lists.xensource.com wrote on 12/20/2006 11:42:06 AM:
>
> It should just be a fault, but I see that EPERM might not be blindly
> interpreted as EFAULT.
>
> On Wed, 2006-12-20 at 10:11 -0500, Stefan Berger wrote:
> >
> > Hello George,
> >
> > what's the to-be-expected side-effect if a hook like this is enforced
> > (rc != 0)?
> >
> > @@ -2217,6 +2222,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);
> >
> >
> > Stefan
> >
> > xense-devel-bounces@lists.xensource.com wrote on 12/20/2006 09:08:40
> > AM:
> >
> > > 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
> > operations
> > > in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> > > Berger/Watson/IBM] _______________________________________________
> > > Xense-devel mailing list
> > > Xense-devel@lists.xensource.com
> > > http://lists.xensource.com/xense-devel
> --
> George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 6742 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] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 17:39 ` Stefan Berger
@ 2006-12-20 18:02 ` George S. Coker, II
2006-12-20 18:19 ` George S. Coker, II
2006-12-20 18:32 ` Stefan Berger
0 siblings, 2 replies; 10+ messages in thread
From: George S. Coker, II @ 2006-12-20 18:02 UTC (permalink / raw)
To: Stefan Berger
Cc: xense-devel-bounces, xen-devel, xense-devel, xen-devel-bounces
On Wed, 2006-12-20 at 12:39 -0500, Stefan Berger wrote:
>
> George,
>
> i tried to simulate this hook by deactivating the
> MMU_NORMAL_PT_UPDATE like this:
>
>
> diff -r f80f1cc7f85e xen/arch/x86/mm.c
> --- a/xen/arch/x86/mm.c Wed Dec 20 09:48:21 2006 +0000
> +++ b/xen/arch/x86/mm.c Wed Dec 20 12:30:39 2006 -0500
> @@ -2217,6 +2217,9 @@ int do_mmu_update(
> */
> case MMU_NORMAL_PT_UPDATE:
>
> + if (!IS_PRIV(current->domain))
> + goto out;
> +
> gmfn = req.ptr >> PAGE_SHIFT;
> mfn = gmfn_to_mfn(d, gmfn);
>
>
> Domain-0 starts up fine. When trying to start a guest domain, the
> effect on the application level was that an 'xm create <vmconfig
> file>' threw no error, but the domain never appeared in the domain
> list - I suppose it dies.
>
I recall that Domain-0 needs to do some mapping of the other domains
pages during construction. This will certainly fail in your example as
you have shown. The effect is the domain is never built, but this is
not the only hypercall involved in domain construction and so I don't
doubt that there might be orphaned pages (for example) that belonging to
a nonexistent domain because of the other hypercalls that were not
subject to the policy you have simulated here. IOW, I don't think that
one failed security check should have to clean up after security checks
that may have passed under a security policy. However, the control
plane may need to be enhanced to better accommodate faults and perform
cleanup.
> Otherwise, I saw you have two hooks for pause / unpause of a domain. I
> wonder whether this should not rather be only one hook 'pausing' that
> allows one to pause / unpause or disallows both operations, or why
> would someone be allow to pause a domain and not unpause it later?
>
Two hooks exist because they have two different code paths. To maintain
flexibility and consistency in the XSM, we have two different hooks. A
given security module might register the same function twice and use the
same permission.
> Stefan
>
> xen-devel-bounces@lists.xensource.com wrote on 12/20/2006 11:42:06 AM:
>
> >
> > It should just be a fault, but I see that EPERM might not be blindly
> > interpreted as EFAULT.
> >
> > On Wed, 2006-12-20 at 10:11 -0500, Stefan Berger wrote:
> > >
> > > Hello George,
> > >
> > > what's the to-be-expected side-effect if a hook like this is
> enforced
> > > (rc != 0)?
> > >
> > > @@ -2217,6 +2222,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);
> > >
> > >
> > > Stefan
> > >
> > > xense-devel-bounces@lists.xensource.com wrote on 12/20/2006
> 09:08:40
> > > AM:
> > >
> > > > 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
> > > operations
> > > > in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> > > > Berger/Watson/IBM]
> _______________________________________________
> > > > Xense-devel mailing list
> > > > Xense-devel@lists.xensource.com
> > > > http://lists.xensource.com/xense-devel
> > --
> > George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xensource.com
> > http://lists.xensource.com/xen-devel
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 18:02 ` George S. Coker, II
@ 2006-12-20 18:19 ` George S. Coker, II
2006-12-20 18:32 ` Stefan Berger
1 sibling, 0 replies; 10+ messages in thread
From: George S. Coker, II @ 2006-12-20 18:19 UTC (permalink / raw)
To: Stefan Berger
Cc: xense-devel-bounces, xen-devel, xense-devel, xen-devel-bounces
On Wed, 2006-12-20 at 13:02 -0500, George S. Coker, II wrote:
> On Wed, 2006-12-20 at 12:39 -0500, Stefan Berger wrote:
> >
> > George,
> >
> > i tried to simulate this hook by deactivating the
> > MMU_NORMAL_PT_UPDATE like this:
> >
> >
> > diff -r f80f1cc7f85e xen/arch/x86/mm.c
> > --- a/xen/arch/x86/mm.c Wed Dec 20 09:48:21 2006 +0000
> > +++ b/xen/arch/x86/mm.c Wed Dec 20 12:30:39 2006 -0500
> > @@ -2217,6 +2217,9 @@ int do_mmu_update(
> > */
> > case MMU_NORMAL_PT_UPDATE:
> >
> > + if (!IS_PRIV(current->domain))
> > + goto out;
> > +
> > gmfn = req.ptr >> PAGE_SHIFT;
> > mfn = gmfn_to_mfn(d, gmfn);
> >
> >
> > Domain-0 starts up fine. When trying to start a guest domain, the
> > effect on the application level was that an 'xm create <vmconfig
> > file>' threw no error, but the domain never appeared in the domain
> > list - I suppose it dies.
> >
>
> I recall that Domain-0 needs to do some mapping of the other domains
> pages during construction. This will certainly fail in your example as
> you have shown. The effect is the domain is never built, but this is
> not the only hypercall involved in domain construction and so I don't
> doubt that there might be orphaned pages (for example) that belonging to
> a nonexistent domain because of the other hypercalls that were not
> subject to the policy you have simulated here. IOW, I don't think that
> one failed security check should have to clean up after security checks
> that may have passed under a security policy. However, the control
> plane may need to be enhanced to better accommodate faults and perform
> cleanup.
>
It may well be that this exposes that the caller expects certain
operations to be atomic but clearly are not. It may suggest that some
functions need to be reworked so that they can fault properly.
> > Otherwise, I saw you have two hooks for pause / unpause of a domain. I
> > wonder whether this should not rather be only one hook 'pausing' that
> > allows one to pause / unpause or disallows both operations, or why
> > would someone be allow to pause a domain and not unpause it later?
> >
>
> Two hooks exist because they have two different code paths. To maintain
> flexibility and consistency in the XSM, we have two different hooks. A
> given security module might register the same function twice and use the
> same permission.
>
> > Stefan
> >
> > xen-devel-bounces@lists.xensource.com wrote on 12/20/2006 11:42:06 AM:
> >
> > >
> > > It should just be a fault, but I see that EPERM might not be blindly
> > > interpreted as EFAULT.
> > >
> > > On Wed, 2006-12-20 at 10:11 -0500, Stefan Berger wrote:
> > > >
> > > > Hello George,
> > > >
> > > > what's the to-be-expected side-effect if a hook like this is
> > enforced
> > > > (rc != 0)?
> > > >
> > > > @@ -2217,6 +2222,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);
> > > >
> > > >
> > > > Stefan
> > > >
> > > > xense-devel-bounces@lists.xensource.com wrote on 12/20/2006
> > 09:08:40
> > > > AM:
> > > >
> > > > > 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
> > > > operations
> > > > > in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> > > > > Berger/Watson/IBM]
> > _______________________________________________
> > > > > Xense-devel mailing list
> > > > > Xense-devel@lists.xensource.com
> > > > > http://lists.xensource.com/xense-devel
> > > --
> > > George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
> > >
> > >
> > > _______________________________________________
> > > Xen-devel mailing list
> > > Xen-devel@lists.xensource.com
> > > http://lists.xensource.com/xen-devel
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 18:02 ` George S. Coker, II
2006-12-20 18:19 ` George S. Coker, II
@ 2006-12-20 18:32 ` Stefan Berger
2006-12-20 18:40 ` George S. Coker, II
1 sibling, 1 reply; 10+ messages in thread
From: Stefan Berger @ 2006-12-20 18:32 UTC (permalink / raw)
To: George S. Coker, II
Cc: xense-devel-bounces, xen-devel, xense-devel, xen-devel-bounces
[-- Attachment #1.1: Type: text/plain, Size: 6933 bytes --]
xen-devel-bounces@lists.xensource.com wrote on 12/20/2006 01:02:26 PM:
> On Wed, 2006-12-20 at 12:39 -0500, Stefan Berger wrote:
> >
> > George,
> >
> > i tried to simulate this hook by deactivating the
> > MMU_NORMAL_PT_UPDATE like this:
> >
> >
> > diff -r f80f1cc7f85e xen/arch/x86/mm.c
> > --- a/xen/arch/x86/mm.c Wed Dec 20 09:48:21 2006 +0000
> > +++ b/xen/arch/x86/mm.c Wed Dec 20 12:30:39 2006 -0500
> > @@ -2217,6 +2217,9 @@ int do_mmu_update(
> > */
> > case MMU_NORMAL_PT_UPDATE:
> >
> > + if (!IS_PRIV(current->domain))
> > + goto out;
> > +
> > gmfn = req.ptr >> PAGE_SHIFT;
> > mfn = gmfn_to_mfn(d, gmfn);
> >
> >
> > Domain-0 starts up fine. When trying to start a guest domain, the
> > effect on the application level was that an 'xm create <vmconfig
> > file>' threw no error, but the domain never appeared in the domain
> > list - I suppose it dies.
> >
>
> I recall that Domain-0 needs to do some mapping of the other domains
> pages during construction. This will certainly fail in your example as
> you have shown. The effect is the domain is never built, but this is
In the above patch 'goto out' is ONLY called if the domain calling this
function is NOT a privileged domain. Domain-0 is privileged and will
therefore not 'goto out'. So I think it's more the guest domain that's
trying to call this function and fails.
> not the only hypercall involved in domain construction and so I don't
> doubt that there might be orphaned pages (for example) that belonging to
> a nonexistent domain because of the other hypercalls that were not
> subject to the policy you have simulated here. IOW, I don't think that
> one failed security check should have to clean up after security checks
> that may have passed under a security policy. However, the control
> plane may need to be enhanced to better accommodate faults and perform
> cleanup.
>
> > Otherwise, I saw you have two hooks for pause / unpause of a domain. I
> > wonder whether this should not rather be only one hook 'pausing' that
> > allows one to pause / unpause or disallows both operations, or why
> > would someone be allow to pause a domain and not unpause it later?
> >
>
> Two hooks exist because they have two different code paths. To maintain
> flexibility and consistency in the XSM, we have two different hooks. A
> given security module might register the same function twice and use the
> same permission.
So there are policies that might allow you to pause but not unpause?
Stefan
>
> > Stefan
> >
> > xen-devel-bounces@lists.xensource.com wrote on 12/20/2006 11:42:06 AM:
> >
> > >
> > > It should just be a fault, but I see that EPERM might not be blindly
> > > interpreted as EFAULT.
> > >
> > > On Wed, 2006-12-20 at 10:11 -0500, Stefan Berger wrote:
> > > >
> > > > Hello George,
> > > >
> > > > what's the to-be-expected side-effect if a hook like this is
> > enforced
> > > > (rc != 0)?
> > > >
> > > > @@ -2217,6 +2222,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);
> > > >
> > > >
> > > > Stefan
> > > >
> > > > xense-devel-bounces@lists.xensource.com wrote on 12/20/2006
> > 09:08:40
> > > > AM:
> > > >
> > > > > 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
> > > > operations
> > > > > in 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 "xsm-121906-xen-unstable.diff" deleted by Stefan
> > > > > Berger/Watson/IBM]
> > _______________________________________________
> > > > > Xense-devel mailing list
> > > > > Xense-devel@lists.xensource.com
> > > > > http://lists.xensource.com/xense-devel
> > > --
> > > George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
> > >
> > >
> > > _______________________________________________
> > > Xen-devel mailing list
> > > Xen-devel@lists.xensource.com
> > > http://lists.xensource.com/xen-devel
> --
> George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 10270 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] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 18:32 ` Stefan Berger
@ 2006-12-20 18:40 ` George S. Coker, II
0 siblings, 0 replies; 10+ messages in thread
From: George S. Coker, II @ 2006-12-20 18:40 UTC (permalink / raw)
To: Stefan Berger
Cc: xense-devel-bounces, xen-devel, xense-devel, xen-devel-bounces
>
> So there are policies that might allow you to pause but not unpause?
>
I think I can conceive of a policy where a domain has permission to
pause a group of domains, but may not have the permission to unpause
them, i.e. to ensure that a given workflow process is one-way.
> Stefan
>
--
George S. Coker, II <gscoker@alpha.ncsc.mil> 443-479-6944
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-20 14:08 [Xense-devel] [PATCH] [1/4] XSM Framework George S. Coker, II
2006-12-20 15:11 ` Stefan Berger
@ 2006-12-21 10:53 ` Keir Fraser
2006-12-21 20:39 ` Peter A. Loscocco
1 sibling, 1 reply; 10+ messages in thread
From: Keir Fraser @ 2006-12-21 10:53 UTC (permalink / raw)
To: George S. Coker, II, xen-devel, xense-devel
On 20/12/06 14:08, "George S. Coker, II" <gscoker@alpha.ncsc.mil> wrote:
> 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.
ACM code is currently present in xen, xend and in the xm command-line tool.
Do the XSM patches remove all this ACM-specific code, since (I believe) XSM
logically subsumes ACM?
-- Keir
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Xense-devel] [PATCH] [1/4] XSM Framework
2006-12-21 10:53 ` Keir Fraser
@ 2006-12-21 20:39 ` Peter A. Loscocco
0 siblings, 0 replies; 10+ messages in thread
From: Peter A. Loscocco @ 2006-12-21 20:39 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel, George S. Coker, II, xense-devel
On Thu, 2006-12-21 at 10:53 +0000, Keir Fraser wrote:
> ACM code is currently present in xen, xend and in the xm command-line tool.
> Do the XSM patches remove all this ACM-specific code, since (I believe) XSM
> logically subsumes ACM?
It is the intention that XSM would subsume ACM with the functionality
that ACM provides being in an ACM-specific XSM module. In Xen itself, it
is like that now. The ACM code is in the ACM module.
There still needs to be some thought given to what the correct user-
space interfaces should be. The current implementation uses the existing
ACM interfaces. There are different implementations of the functions
behind those interfaces for each XSM module. Which set of functions is
used depends on which XSM module has been installed.
--
Peter Loscocco
National Security Agency
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-12-21 20:39 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-20 14:08 [Xense-devel] [PATCH] [1/4] XSM Framework George S. Coker, II
2006-12-20 15:11 ` Stefan Berger
2006-12-20 16:42 ` George S. Coker, II
2006-12-20 17:39 ` Stefan Berger
2006-12-20 18:02 ` George S. Coker, II
2006-12-20 18:19 ` George S. Coker, II
2006-12-20 18:32 ` Stefan Berger
2006-12-20 18:40 ` George S. Coker, II
2006-12-21 10:53 ` Keir Fraser
2006-12-21 20:39 ` Peter A. Loscocco
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.