diff -r 8117f6684991 -r 091fc390e6f1 Config.mk --- a/Config.mk Wed Mar 7 16:21:21 2007 +0000 +++ b/Config.mk Thu Mar 8 14:04:28 2007 -0500 @@ -56,6 +56,10 @@ LDFLAGS += $(foreach i, $(EXTRA_LIB), -L LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i)) CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i)) +#Enable XSM security module. Enabling XSM requires selection of an +#XSM security module. +XSM_ENABLE ?= y + # If ACM_SECURITY = y, then the access control module is compiled # into Xen and the policy type can be set by the boot policy file # y - Build the Xen ACM framework diff -r 8117f6684991 -r 091fc390e6f1 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Wed Mar 7 16:21:21 2007 +0000 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Thu Mar 8 14:04:28 2007 -0500 @@ -402,6 +402,12 @@ HYPERVISOR_kexec_op( return _hypercall2(int, kexec_op, op, args); } +static inline int +HYPERVISOR_xsm_op( + int cmd, void *arg) +{ + return _hypercall2(int, xsm_op, cmd, arg); +} #endif /* __HYPERCALL_H__ */ diff -r 8117f6684991 -r 091fc390e6f1 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Wed Mar 7 16:21:21 2007 +0000 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Thu Mar 8 14:04:28 2007 -0500 @@ -403,4 +403,11 @@ HYPERVISOR_kexec_op( return _hypercall2(int, kexec_op, op, args); } +static inline int +HYPERVISOR_xsm_op( + int cmd, void *arg) +{ + return _hypercall2(int, xsm_op, cmd, arg); +} + #endif /* __HYPERCALL_H__ */ diff -r 8117f6684991 -r 091fc390e6f1 xen/Makefile --- a/xen/Makefile Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/Makefile Thu Mar 8 14:04:28 2007 -0500 @@ -56,6 +56,7 @@ _clean: delete-unfresh-files $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean $(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean rm -f include/asm *.o $(TARGET)* *~ core rm -f include/asm-*/asm-offsets.h @@ -138,7 +139,7 @@ build-headers: build-headers: $(MAKE) -C include/public/foreign -SUBDIRS = acm arch/$(TARGET_ARCH) common drivers +SUBDIRS = xsm acm arch/$(TARGET_ARCH) common drivers define all_sources ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \ find include -name 'asm-*' -prune -o -name '*.h' -print; \ diff -r 8117f6684991 -r 091fc390e6f1 xen/Rules.mk --- a/xen/Rules.mk Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/Rules.mk Thu Mar 8 14:04:28 2007 -0500 @@ -47,10 +47,12 @@ HDRS := $(filter-out %/asm-offsets.h,$( # Note that link order matters! ALL_OBJS-y += $(BASEDIR)/common/built_in.o ALL_OBJS-y += $(BASEDIR)/drivers/built_in.o +ALL_OBJS-y += $(BASEDIR)/xsm/built_in.o ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o ALL_OBJS-y += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o CFLAGS-y += -g -D__XEN__ +CFLAGS-$(XSM_ENABLE) += -DXSM_ENABLE CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY CFLAGS-$(verbose) += -DVERBOSE CFLAGS-$(crash_debug) += -DCRASH_DEBUG diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/domctl.c Thu Mar 8 14:04:28 2007 -0500 @@ -25,6 +25,7 @@ #include #include #include +#include long arch_do_domctl( struct xen_domctl *domctl, @@ -42,6 +43,13 @@ long arch_do_domctl( d = rcu_lock_domain_by_id(domctl->domain); if ( d != NULL ) { + ret = xsm_shadow_control(d, domctl->u.shadow_op.op); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + ret = paging_domctl(d, &domctl->u.shadow_op, guest_handle_cast(u_domctl, void)); @@ -64,6 +72,13 @@ long arch_do_domctl( ret = -ESRCH; if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) break; + + ret = xsm_ioport_permission(d, fp, domctl->u.ioport_permission.allow_access); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } if ( np == 0 ) ret = 0; @@ -88,6 +103,13 @@ long arch_do_domctl( if ( unlikely(!mfn_valid(mfn)) || unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) ) break; + + ret = xsm_getpageframeinfo(mfn); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } page = mfn_to_page(mfn); @@ -166,6 +188,10 @@ long arch_do_domctl( struct page_info *page; unsigned long mfn = arr32[j]; + ret = xsm_getpageframeinfo(mfn); + if ( ret ) + continue; + page = mfn_to_page(mfn); if ( likely(mfn_valid(mfn) && get_page(page, d)) ) @@ -225,6 +251,13 @@ long arch_do_domctl( ret = -EINVAL; if ( d != NULL ) { + ret = xsm_getmemlist(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + ret = 0; spin_lock(&d->page_alloc_lock); @@ -264,6 +297,13 @@ long arch_do_domctl( if ( unlikely(d == NULL) ) break; + ret = xsm_hypercall_init(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + mfn = gmfn_to_mfn(d, gmfn); ret = -EACCES; @@ -298,6 +338,10 @@ long arch_do_domctl( ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; + + ret = xsm_hvmcontext(d, domctl->cmd); + if ( ret ) + goto sethvmcontext_out; ret = -EINVAL; if ( !is_hvm_domain(d) ) @@ -330,6 +374,10 @@ long arch_do_domctl( if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; + ret = xsm_hvmcontext(d, domctl->cmd); + if ( ret ) + goto gethvmcontext_out; + ret = -EINVAL; if ( !is_hvm_domain(d) ) goto gethvmcontext_out; @@ -381,6 +429,13 @@ long arch_do_domctl( if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; + ret = xsm_address_size(d, domctl->cmd); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + switch ( domctl->u.address_size.size ) { #ifdef CONFIG_COMPAT @@ -407,6 +462,13 @@ long arch_do_domctl( ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; + + ret = xsm_address_size(d, domctl->cmd); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } domctl->u.address_size.size = BITS_PER_GUEST_LONG(d); diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/hvm/hvm.c Thu Mar 8 14:04:28 2007 -0500 @@ -1,3 +1,4 @@ + /* * hvm.c: Common hardware virtual machine abstractions. * @@ -715,6 +716,10 @@ static int hvmop_set_pci_intx_level( if ( d == NULL ) return -ESRCH; + rc = xsm_hvm_set_pci_intx_level(d); + if ( rc ) + goto out; + rc = -EINVAL; if ( !is_hvm_domain(d) ) goto out; @@ -758,6 +763,10 @@ static int hvmop_set_isa_irq_level( if ( d == NULL ) return -ESRCH; + rc = xsm_hvm_set_isa_irq_level(d); + if ( rc ) + goto out; + rc = -EINVAL; if ( !is_hvm_domain(d) ) goto out; @@ -800,6 +809,10 @@ static int hvmop_set_pci_link_route( d = rcu_lock_domain_by_id(op.domid); if ( d == NULL ) return -ESRCH; + + rc = xsm_hvm_set_pci_link_route(d); + if ( rc ) + goto out; rc = -EINVAL; if ( !is_hvm_domain(d) ) @@ -844,6 +857,10 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( d == NULL ) return -ESRCH; + + rc = xsm_hvm_param(d, op); + if ( rc ) + goto param_fail; rc = -EINVAL; if ( !is_hvm_domain(d) ) diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/irq.c Thu Mar 8 14:04:28 2007 -0500 @@ -16,6 +16,7 @@ #include #include #include +#include /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */ int opt_noirqbalance = 0; @@ -333,6 +334,9 @@ int pirq_guest_unmask(struct domain *d) irq < NR_IRQS; irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) ) { + if ( xsm_pirq_unmask(d, irq) ) + continue; + if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) ) __pirq_guest_eoi(d, irq); } diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/mm.c Thu Mar 8 14:04:28 2007 -0500 @@ -109,6 +109,7 @@ #include #include #include +#include #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a) @@ -2017,6 +2018,10 @@ int do_mmuext_op( type = PGT_l4_page_table; pin_page: + rc = xsm_memory_pin_page(current->domain, mfn); + if ( rc ) + break; + /* Ignore pinning of invalid paging levels. */ if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) ) break; @@ -2295,6 +2300,10 @@ int do_mmu_update( * MMU_NORMAL_PT_UPDATE: Normal update to any level of page table. */ case MMU_NORMAL_PT_UPDATE: + + rc = xsm_mmu_normal_update(current->domain, req.val); + if ( rc ) + goto out; gmfn = req.ptr >> PAGE_SHIFT; mfn = gmfn_to_mfn(d, gmfn); @@ -2386,6 +2395,10 @@ int do_mmu_update( mfn = req.ptr >> PAGE_SHIFT; gpfn = req.val; + rc = xsm_mmu_machphys_update(current->domain, mfn); + if ( rc ) + goto out; + if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) ) { MEM_LOG("Could not get page for mach->phys update"); @@ -2720,6 +2733,10 @@ int do_update_va_mapping(unsigned long v if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) ) return -EINVAL; + rc = xsm_update_va_mapping(current->domain, val.l1); + if ( rc ) + return rc; + LOCK_BIGLOCK(d); pl1e = guest_map_l1e(v, va, &gl1mfn); @@ -2976,6 +2993,13 @@ long arch_memory_op(int op, XEN_GUEST_HA else if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL ) return -ESRCH; + if ( xsm_add_to_physmap(current->domain, d) ) + { + if (xatp.domid != DOMID_SELF) + rcu_unlock_domain(d); + return -EPERM; + } + switch ( xatp.space ) { case XENMAPSPACE_shared_info: @@ -3052,6 +3076,14 @@ long arch_memory_op(int op, XEN_GUEST_HA else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL ) return -ESRCH; + rc = xsm_domain_memory_map(current->domain, d); + if ( rc ) + { + if (fmap.domid != DOMID_SELF) + rcu_unlock_domain(d); + return rc; + } + rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer, fmap.map.nr_entries) ? -EFAULT : 0; d->arch.nr_e820 = fmap.map.nr_entries; @@ -3085,9 +3117,14 @@ long arch_memory_op(int op, XEN_GUEST_HA struct xen_memory_map memmap; XEN_GUEST_HANDLE(e820entry_t) buffer; int count; - + int rc; + if ( !IS_PRIV(current->domain) ) return -EINVAL; + + rc = xsm_machine_memory_map(); + if ( rc ) + return rc; if ( copy_from_guest(&memmap, arg, 1) ) return -EFAULT; diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/physdev.c Thu Mar 8 14:04:28 2007 -0500 @@ -12,6 +12,7 @@ #include #include #include +#include #ifndef COMPAT typedef long ret_t; @@ -36,6 +37,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EFAULT; if ( copy_from_guest(&eoi, arg, 1) != 0 ) break; + ret = xsm_pirq_unmask(current->domain, eoi.irq); + if ( ret ) + break; ret = pirq_guest_eoi(current->domain, eoi.irq); break; } @@ -55,6 +59,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EINVAL; if ( (irq < 0) || (irq >= NR_IRQS) ) break; + ret = xsm_pirq_status(current->domain, irq); + if ( ret ) + break; irq_status_query.flags = 0; if ( pirq_acktype(irq) != 0 ) irq_status_query.flags |= XENIRQSTAT_needs_eoi; @@ -72,6 +79,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EPERM; if ( !IS_PRIV(current->domain) ) break; + ret = xsm_apic(current->domain, cmd); + if ( ret ) + break; ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value); if ( copy_to_guest(arg, &apic, 1) != 0 ) ret = -EFAULT; @@ -85,6 +95,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H break; ret = -EPERM; if ( !IS_PRIV(current->domain) ) + break; + ret = xsm_apic(current->domain, cmd); + if ( ret ) break; ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value); break; @@ -101,8 +114,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H if ( !IS_PRIV(current->domain) ) break; + ret = xsm_assign_vector(current->domain, irq_op.irq); + if ( ret ) + break; + ret = -EINVAL; + irq = irq_op.irq; - ret = -EINVAL; if ( (irq < 0) || (irq >= NR_IRQS) ) break; diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/platform_hypercall.c Thu Mar 8 14:04:28 2007 -0500 @@ -22,6 +22,7 @@ #include #include #include "cpu/mtrr/mtrr.h" +#include #ifndef COMPAT typedef long ret_t; @@ -50,6 +51,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe { case XENPF_settime: { + ret = xsm_xen_settime(); + if ( ret ) + break; + do_settime(op->u.settime.secs, op->u.settime.nsecs, op->u.settime.system_time); @@ -59,6 +64,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe case XENPF_add_memtype: { + ret = xsm_memtype(op->cmd); + if ( ret ) + break; + ret = mtrr_add_page( op->u.add_memtype.mfn, op->u.add_memtype.nr_mfns, @@ -77,6 +86,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe case XENPF_del_memtype: { + ret = xsm_memtype(op->cmd); + if ( ret ) + break; + if (op->u.del_memtype.handle == 0 /* mtrr/main.c otherwise does a lookup */ && (int)op->u.del_memtype.reg >= 0) @@ -96,6 +109,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe unsigned int nr_mfns; mtrr_type type; + ret = xsm_memtype(op->cmd); + if ( ret ) + break; + ret = -EINVAL; if ( op->u.read_memtype.reg < num_var_ranges ) { @@ -111,6 +128,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe case XENPF_microcode_update: { extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len); + + ret = xsm_microcode(); + if (ret) + break; + #ifndef COMPAT ret = microcode_update(op->u.microcode.data, op->u.microcode.length); @@ -127,6 +149,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe { extern int opt_noirqbalance; int quirk_id = op->u.platform_quirk.quirk_id; + + ret = xsm_platform_quirk(quirk_id); + if ( ret ) + break; + switch ( quirk_id ) { case QUIRK_NOIRQBALANCING: diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/setup.c Thu Mar 8 14:04:28 2007 -0500 @@ -33,6 +33,7 @@ #include #include #include +#include extern void dmi_scan_machine(void); extern void generic_apic_probe(void); @@ -655,6 +656,8 @@ void __init __start_xen(multiboot_info_t percpu_init_areas(); + xsm_init(&initrdidx, mbi, initial_images_start); + init_idle_domain(); trap_init(); @@ -737,6 +740,8 @@ void __init __start_xen(multiboot_info_t /* Post-create hook sets security label. */ acm_post_domain0_create(dom0->domain_id); + + xsm_complete_init(dom0); /* Grab the DOM0 command line. */ cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/sysctl.c --- a/xen/arch/x86/sysctl.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/sysctl.c Thu Mar 8 14:04:28 2007 -0500 @@ -23,6 +23,7 @@ #include #include #include +#include long arch_do_sysctl( struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) @@ -35,6 +36,10 @@ long arch_do_sysctl( case XEN_SYSCTL_physinfo: { xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo; + + ret = xsm_physinfo(); + if ( ret ) + break; pi->threads_per_core = cpus_weight(cpu_sibling_map[0]); diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/x86_32/entry.S Thu Mar 8 14:04:28 2007 -0500 @@ -671,6 +671,7 @@ ENTRY(hypercall_table) .long do_sysctl /* 35 */ .long do_domctl .long do_kexec_op + .long do_xsm_op .rept NR_hypercalls-((.-hypercall_table)/4) .long do_ni_hypercall .endr @@ -714,6 +715,7 @@ ENTRY(hypercall_args_table) .byte 1 /* do_sysctl */ /* 35 */ .byte 1 /* do_domctl */ .byte 2 /* do_kexec_op */ + .byte 1 /* do_xsm_op */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/x86_32/mm.c Thu Mar 8 14:04:28 2007 -0500 @@ -199,6 +199,7 @@ long subarch_memory_op(int op, XEN_GUEST switch ( op ) { case XENMEM_machphys_mfn_list: + if ( copy_from_guest(&xmml, arg, 1) ) return -EFAULT; diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_32/xen.lds.S --- a/xen/arch/x86/x86_32/xen.lds.S Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/x86_32/xen.lds.S Thu Mar 8 14:04:28 2007 -0500 @@ -63,6 +63,7 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall1.init) } :text __initcall_end = .; + .xsm_initcall.init : { __xsm_initcall_start = .; *(.xsm_initcall.init) __xsm_initcall_end = .; } . = ALIGN(PAGE_SIZE); __init_end = .; diff -r 8117f6684991 -r 091fc390e6f1 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/arch/x86/x86_64/entry.S Thu Mar 8 14:04:28 2007 -0500 @@ -587,6 +587,7 @@ ENTRY(hypercall_table) .quad do_sysctl /* 35 */ .quad do_domctl .quad do_kexec_op + .quad do_xsm_op .rept NR_hypercalls-((.-hypercall_table)/8) .quad do_ni_hypercall .endr @@ -630,6 +631,7 @@ ENTRY(hypercall_args_table) .byte 1 /* do_sysctl */ /* 35 */ .byte 1 /* do_domctl */ .byte 2 /* do_kexec */ + .byte 1 /* do_xsm_op */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r 8117f6684991 -r 091fc390e6f1 xen/common/domain.c --- a/xen/common/domain.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/domain.c Thu Mar 8 14:04:28 2007 -0500 @@ -28,6 +28,7 @@ #include #include #include +#include /* Protect updates/reads (resp.) of domain_list and domain_hash. */ DEFINE_SPINLOCK(domlist_update_lock); @@ -156,6 +157,9 @@ struct domain *domain_create(domid_t dom d->is_hvm = 1; rangeset_domain_initialise(d); + + if ( xsm_alloc_security_domain(d) ) + goto fail1; if ( !is_idle_domain(d) ) { @@ -357,6 +361,8 @@ static void complete_domain_destroy(stru arch_domain_destroy(d); + xsm_free_security_domain(d); + free_domain(d); send_guest_global_virq(dom0, VIRQ_DOM_EXC); diff -r 8117f6684991 -r 091fc390e6f1 xen/common/domctl.c --- a/xen/common/domctl.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/domctl.c Thu Mar 8 14:04:28 2007 -0500 @@ -24,6 +24,7 @@ #include #include #include +#include extern long arch_do_domctl( struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); @@ -126,6 +127,8 @@ void getdomaininfo(struct domain *d, str info->ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref; else info->ssidref = ACM_DEFAULT_SSID; + + xsm_security_domaininfo(d, info); info->tot_pages = d->tot_pages; info->max_pages = d->max_pages; @@ -207,6 +210,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; + ret = xsm_setvcpucontext(d); + if ( ret ) + goto svc_out; + ret = -EINVAL; if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) ) goto svc_out; @@ -254,12 +261,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { + ret = xsm_pausedomain(d); + if ( ret ) + goto pausedomain_out; + ret = -EINVAL; if ( d != current->domain ) { domain_pause_by_systemcontroller(d); ret = 0; } + pausedomain_out: rcu_unlock_domain(d); } } @@ -271,6 +283,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { + ret = xsm_unpausedomain(d); + if ( ret ) + goto unpausedomain_out; + ret = -EINVAL; if ( (d != current->domain) && (d->vcpu[0] != NULL) && test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) ) @@ -278,6 +294,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc domain_unpause_by_systemcontroller(d); ret = 0; } + + unpausedomain_out: rcu_unlock_domain(d); } } @@ -291,10 +309,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { + ret = xsm_resumedomain(d); + if ( ret ) + goto resumedomain_out; + ret = 0; if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) ) for_each_vcpu ( d, v ) vcpu_wake(v); + + resumedomain_out: rcu_unlock_domain(d); } } @@ -310,6 +334,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( supervisor_mode_kernel || (op->u.createdomain.flags & ~XEN_DOMCTL_CDF_hvm_guest) ) return -EINVAL; + + ret = xsm_createdomain(op); + if ( ret ) + goto createdomain_out; dom = op->domain; if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) ) @@ -343,12 +371,19 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( (d = domain_create(dom, domcr_flags)) == NULL ) break; + xsm_createdomain_post(d, op); + ret = 0; memcpy(d->handle, op->u.createdomain.handle, sizeof(xen_domain_handle_t)); op->domain = d->domain_id; + + createdomain_out: + if ( ret ) + xsm_createdomain_fail(op); + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; } @@ -365,6 +400,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) + break; + + ret = xsm_max_vcpus(d); + if ( ret ) break; /* Needed, for example, to ensure writable p.t. state is synced. */ @@ -403,12 +442,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( d != NULL ) { + ret = xsm_destroydomain(d); + if ( ret ) + goto destroydomain_out; + ret = -EINVAL; if ( d != current->domain ) { domain_kill(d); ret = 0; } + destroydomain_out: rcu_unlock_domain(d); } } @@ -426,6 +470,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; + ret = xsm_vcpuaffinity(op->cmd, d); + if ( ret ) + goto vcpuaffinity_out; + ret = -EINVAL; if ( op->u.vcpuaffinity.vcpu >= MAX_VIRT_CPUS ) goto vcpuaffinity_out; @@ -460,10 +508,15 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) break; + ret = xsm_scheduler(d); + if ( ret ) + goto scheduler_op_out; + ret = sched_adjust(d, &op->u.scheduler_op); if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; + scheduler_op_out: rcu_unlock_domain(d); } break; @@ -492,12 +545,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc break; } + ret = xsm_getdomaininfo(d); + if ( ret ) + goto getdomaininfo_out; + getdomaininfo(d, &op->u.getdomaininfo); op->domain = op->u.getdomaininfo.domain; if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; + getdomaininfo_out: rcu_read_unlock(&domlist_read_lock); } break; @@ -511,6 +569,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) break; + + ret = xsm_getvcpucontext(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } ret = -EINVAL; if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS ) @@ -568,6 +633,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) break; + ret = xsm_getvcpuinfo(d); + if ( ret ) + goto getvcpuinfo_out; + ret = -EINVAL; if ( op->u.getvcpuinfo.vcpu >= MAX_VIRT_CPUS ) goto getvcpuinfo_out; @@ -603,6 +672,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; + ret = xsm_setdomainmaxmem(d); + if ( ret ) + goto max_mem_out; + ret = -EINVAL; new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10); @@ -617,6 +690,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc } spin_unlock(&d->page_alloc_lock); + max_mem_out: rcu_unlock_domain(d); } break; @@ -628,6 +702,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc d = rcu_lock_domain_by_id(op->domain); if ( d != NULL ) { + ret = xsm_setdomainhandle(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + memcpy(d->handle, op->u.setdomainhandle.handle, sizeof(xen_domain_handle_t)); rcu_unlock_domain(d); @@ -643,6 +724,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc d = rcu_lock_domain_by_id(op->domain); if ( d != NULL ) { + ret = xsm_setdebugging(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + if ( op->u.setdebugging.enable ) set_bit(_DOMF_debugging, &d->domain_flags); else @@ -667,11 +755,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; + ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access); + if ( ret ) + goto irq_permission_out; + if ( op->u.irq_permission.allow_access ) ret = irq_permit_access(d, pirq); else ret = irq_deny_access(d, pirq); + irq_permission_out: rcu_unlock_domain(d); } break; @@ -690,12 +783,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc d = rcu_lock_domain_by_id(op->domain); if ( d == NULL ) break; + + ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access); + if ( ret ) + goto iomem_permission_out; if ( op->u.iomem_permission.allow_access ) ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1); else ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1); + iomem_permission_out: rcu_unlock_domain(d); } break; @@ -708,6 +806,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc d = rcu_lock_domain_by_id(op->domain); if ( d != NULL ) { + ret = xsm_domain_settime(d); + if ( ret ) + { + rcu_unlock_domain(d); + break; + } + d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds; rcu_unlock_domain(d); ret = 0; diff -r 8117f6684991 -r 091fc390e6f1 xen/common/event_channel.c --- a/xen/common/event_channel.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/event_channel.c Thu Mar 8 14:04:28 2007 -0500 @@ -30,6 +30,7 @@ #include #include #include +#include #define bucket_from_port(d,p) \ ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET]) @@ -89,8 +90,15 @@ static int get_free_port(struct domain * chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); if ( unlikely(chn == NULL) ) return -ENOMEM; + memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn)); bucket_from_port(d, port) = chn; + + if ( xsm_alloc_security_evtchn(chn) ) + { + xfree(chn); + return -ENOMEM; + } return port; } @@ -120,6 +128,10 @@ static long evtchn_alloc_unbound(evtchn_ if ( (port = get_free_port(d)) < 0 ) ERROR_EXIT(port); chn = evtchn_from_port(d, port); + + rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom); + if ( rc ) + goto out; chn->state = ECS_UNBOUND; if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF ) @@ -176,6 +188,10 @@ static long evtchn_bind_interdomain(evtc if ( (rchn->state != ECS_UNBOUND) || (rchn->u.unbound.remote_domid != ld->domain_id) ) ERROR_EXIT(-EINVAL); + + rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn); + if ( rc ) + goto out; lchn->u.interdomain.remote_dom = rd; lchn->u.interdomain.remote_port = (u16)rport; @@ -231,6 +247,11 @@ static long evtchn_bind_virq(evtchn_bind ERROR_EXIT(port); chn = evtchn_from_port(d, port); + + rc = xsm_evtchn_virq(d, chn, virq, vcpu); + if ( rc ) + goto out; + chn->state = ECS_VIRQ; chn->notify_vcpu_id = vcpu; chn->u.virq = virq; @@ -261,6 +282,11 @@ static long evtchn_bind_ipi(evtchn_bind_ ERROR_EXIT(port); chn = evtchn_from_port(d, port); + + rc = xsm_evtchn_ipi(d, chn, vcpu); + if ( rc ) + goto out; + chn->state = ECS_IPI; chn->notify_vcpu_id = vcpu; @@ -295,6 +321,10 @@ static long evtchn_bind_pirq(evtchn_bind ERROR_EXIT(port); chn = evtchn_from_port(d, port); + + rc = xsm_evtchn_pirq(d, chn, pirq); + if ( rc ) + goto out; d->pirq_to_evtchn[pirq] = port; rc = pirq_guest_bind(d->vcpu[0], pirq, @@ -342,6 +372,10 @@ static long __evtchn_close(struct domain rc = -EINVAL; goto out; } + + rc = xsm_evtchn_close(d1, chn1); + if ( rc ) + goto out; switch ( chn1->state ) { @@ -427,6 +461,8 @@ static long __evtchn_close(struct domain chn1->state = ECS_FREE; chn1->notify_vcpu_id = 0; + xsm_evtchn_close_post(chn1); + out: if ( d2 != NULL ) { @@ -470,6 +506,10 @@ long evtchn_send(unsigned int lport) spin_unlock(&ld->evtchn_lock); return -EINVAL; } + + ret = xsm_evtchn_send(ld, lchn); + if ( ret ) + goto out; switch ( lchn->state ) { @@ -500,6 +540,7 @@ long evtchn_send(unsigned int lport) ret = -EINVAL; } +out: spin_unlock(&ld->evtchn_lock); return ret; @@ -610,6 +651,11 @@ static long evtchn_status(evtchn_status_ } chn = evtchn_from_port(d, port); + + rc = xsm_evtchn_status(d, chn); + if ( rc ) + goto out; + switch ( chn->state ) { case ECS_FREE: @@ -676,6 +722,10 @@ long evtchn_bind_vcpu(unsigned int port, goto out; } + rc = xsm_evtchn_vcpu(d, chn, vcpu_id); + if ( rc ) + goto out; + switch ( chn->state ) { case ECS_VIRQ: @@ -706,6 +756,8 @@ static long evtchn_unmask(evtchn_unmask_ shared_info_t *s = d->shared_info; int port = unmask->port; struct vcpu *v; + int ret = 0; + struct evtchn *chn; spin_lock(&d->evtchn_lock); @@ -715,7 +767,12 @@ static long evtchn_unmask(evtchn_unmask_ return -EINVAL; } - v = d->vcpu[evtchn_from_port(d, port)->notify_vcpu_id]; + chn = evtchn_from_port(d, port); + v = d->vcpu[chn->notify_vcpu_id]; + + ret = xsm_evtchn_unmask(d, chn); + if ( ret ) + goto out; /* * These operations must happen in strict order. Based on @@ -729,9 +786,10 @@ static long evtchn_unmask(evtchn_unmask_ vcpu_mark_events_pending(v); } +out: spin_unlock(&d->evtchn_lock); - return 0; + return ret; } @@ -740,6 +798,7 @@ static long evtchn_reset(evtchn_reset_t domid_t dom = r->dom; struct domain *d; int i; + int rc; if ( dom == DOMID_SELF ) dom = current->domain->domain_id; @@ -749,6 +808,13 @@ static long evtchn_reset(evtchn_reset_t if ( (d = rcu_lock_domain_by_id(dom)) == NULL ) return -ESRCH; + rc = xsm_evtchn_reset(current->domain, d); + if ( rc ) + { + rcu_unlock_domain(d); + return rc; + } + for ( i = 0; port_is_valid(d, i); i++ ) (void)__evtchn_close(d, i); @@ -940,10 +1006,19 @@ void notify_via_xen_event_channel(int lp int evtchn_init(struct domain *d) { + struct evtchn *chn; + int rc; + spin_lock_init(&d->evtchn_lock); if ( get_free_port(d) != 0 ) return -EINVAL; - evtchn_from_port(d, 0)->state = ECS_RESERVED; + chn = evtchn_from_port(d, 0); + chn->state = ECS_RESERVED; + + rc = xsm_evtchn_init(d, chn); + if ( rc ) + return rc; + return 0; } @@ -959,7 +1034,10 @@ void evtchn_destroy(struct domain *d) } for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ ) + { + xsm_free_security_evtchn(d->evtchn[i]); xfree(d->evtchn[i]); + } } /* diff -r 8117f6684991 -r 091fc390e6f1 xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/grant_table.c Thu Mar 8 14:04:28 2007 -0500 @@ -34,6 +34,7 @@ #include #include #include +#include #ifndef max_nr_grant_frames unsigned int max_nr_grant_frames = DEFAULT_MAX_NR_GRANT_FRAMES; @@ -215,6 +216,14 @@ __gnttab_map_grant_ref( return; } + rc = xsm_grant_mapref(ld, rd, op->flags); + if ( rc ) + { + rcu_unlock_domain(rd); + op->status = GNTST_permission_denied; + return; + } + if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) ) { rcu_unlock_domain(rd); @@ -439,6 +448,14 @@ __gnttab_unmap_grant_ref( /* This can happen when a grant is implicitly unmapped. */ gdprintk(XENLOG_INFO, "Could not find domain %d\n", dom); domain_crash(ld); /* naughty... */ + return; + } + + rc = xsm_grant_unmapref(ld, rd); + if ( rc ) + { + rcu_unlock_domain(rd); + op->status = GNTST_permission_denied; return; } @@ -644,6 +661,13 @@ gnttab_setup_table( goto out; } + if ( xsm_grant_setup(current->domain, d) ) + { + rcu_unlock_domain(d); + op.status = GNTST_permission_denied; + goto out; + } + spin_lock(&d->grant_table->lock); if ( (op.nr_frames > nr_grant_frames(d->grant_table)) && @@ -684,6 +708,7 @@ gnttab_query_size( struct gnttab_query_size op; struct domain *d; domid_t dom; + int rc; if ( count != 1 ) return -EINVAL; @@ -709,6 +734,14 @@ gnttab_query_size( { gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); op.status = GNTST_bad_domain; + goto query_out; + } + + rc = xsm_grant_query_size(current->domain, d); + if ( rc ) + { + rcu_unlock_domain(d); + op.status = GNTST_permission_denied; goto query_out; } @@ -855,6 +888,13 @@ gnttab_transfer( page->count_info &= ~(PGC_count_mask|PGC_allocated); free_domheap_page(page); gop.status = GNTST_bad_domain; + goto copyback; + } + + if ( xsm_grant_transfer(d, e) ) + { + rcu_unlock_domain(e); + gop.status = GNTST_permission_denied; goto copyback; } @@ -1077,6 +1117,13 @@ __gnttab_copy( else if ( (dd = rcu_lock_domain_by_id(op->dest.domid)) == NULL ) PIN_FAIL(error_out, GNTST_bad_domain, "couldn't find %d\n", op->dest.domid); + + rc = xsm_grant_copy(sd, dd); + if ( rc ) + { + rc = GNTST_permission_denied; + goto error_out; + } if ( src_is_gref ) { diff -r 8117f6684991 -r 091fc390e6f1 xen/common/kexec.c --- a/xen/common/kexec.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/kexec.c Thu Mar 8 14:04:28 2007 -0500 @@ -20,6 +20,7 @@ #include #include #include +#include #ifndef COMPAT @@ -354,6 +355,10 @@ ret_t do_kexec_op(unsigned long op, XEN_ if ( !IS_PRIV(current->domain) ) return -EPERM; + + ret = xsm_kexec(); + if (ret) + return ret; switch ( op ) { diff -r 8117f6684991 -r 091fc390e6f1 xen/common/memory.c --- a/xen/common/memory.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/memory.c Thu Mar 8 14:04:28 2007 -0500 @@ -22,6 +22,7 @@ #include #include #include +#include struct memop_args { /* INPUT */ @@ -227,6 +228,7 @@ static long translate_gpfn_list( xen_pfn_t gpfn; xen_pfn_t mfn; struct domain *d; + int rc; if ( copy_from_guest(&op, uop, 1) ) return -EFAULT; @@ -269,6 +271,13 @@ static long translate_gpfn_list( } mfn = gmfn_to_mfn(d, gpfn); + + rc = xsm_translate_gpfn_list(current->domain, mfn); + if ( rc ) + { + rcu_unlock_domain(d); + return rc; + } if ( unlikely(__copy_to_guest_offset(op.mfn_list, i, &mfn, 1)) ) { @@ -549,6 +558,14 @@ long do_memory_op(unsigned long cmd, XEN return start_extent; args.domain = d; + rc = xsm_memory_adjust_reservation(current->domain, d); + if ( rc ) + { + if (reservation.domid != DOMID_SELF) + rcu_unlock_domain(d); + return rc; + } + switch ( op ) { case XENMEM_increase_reservation: @@ -593,6 +610,14 @@ long do_memory_op(unsigned long cmd, XEN return -EPERM; else if ( (d = rcu_lock_domain_by_id(domid)) == NULL ) return -ESRCH; + + rc = xsm_memory_stat_reservation(current->domain, d); + if ( rc ) + { + if (domid != DOMID_SELF) + rcu_unlock_domain(d); + return rc; + } rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages; diff -r 8117f6684991 -r 091fc390e6f1 xen/common/schedule.c --- a/xen/common/schedule.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/schedule.c Thu Mar 8 14:04:28 2007 -0500 @@ -32,6 +32,7 @@ #include #include #include +#include /* opt_sched: scheduler - default to credit */ static char opt_sched[10] = "credit"; @@ -433,6 +434,13 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN d = rcu_lock_domain_by_id(sched_remote_shutdown.domain_id); if ( d == NULL ) break; + + ret = xsm_schedop_shutdown(current->domain, d); + if ( ret ) + { + rcu_unlock_domain(d); + return ret; + } domain_shutdown(d, (u8)sched_remote_shutdown.reason); rcu_unlock_domain(d); diff -r 8117f6684991 -r 091fc390e6f1 xen/common/sysctl.c --- a/xen/common/sysctl.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/sysctl.c Thu Mar 8 14:04:28 2007 -0500 @@ -20,6 +20,7 @@ #include #include #include +#include extern long arch_do_sysctl( struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); @@ -45,6 +46,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc { case XEN_SYSCTL_readconsole: { + ret = xsm_readconsole(op->u.readconsole.clear); + if ( ret ) + break; + ret = read_console_ring( guest_handle_cast(op->u.readconsole.buffer, char), &op->u.readconsole.count, @@ -56,6 +61,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc case XEN_SYSCTL_tbuf_op: { + ret = xsm_tbufcontrol(); + if ( ret ) + break; + ret = tb_control(&op->u.tbuf_op); if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; @@ -64,6 +73,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc case XEN_SYSCTL_sched_id: { + ret = xsm_sched_id(); + if ( ret ) + break; + op->u.sched_id.sched_id = sched_id(); if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; @@ -87,6 +100,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc if ( num_domains == op->u.getdomaininfolist.max_domains ) break; + ret = xsm_getdomaininfo(d); + if ( ret ) + continue; + getdomaininfo(d, &info); if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer, @@ -95,7 +112,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc ret = -EFAULT; break; } - + num_domains++; } @@ -114,6 +131,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc #ifdef PERF_COUNTERS case XEN_SYSCTL_perfc_op: { + ret = xsm_perfcontrol(); + if ( ret ) + break; + ret = perfc_control(&op->u.perfc_op); if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; diff -r 8117f6684991 -r 091fc390e6f1 xen/common/xenoprof.c --- a/xen/common/xenoprof.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/common/xenoprof.c Thu Mar 8 14:04:28 2007 -0500 @@ -14,6 +14,7 @@ #include #include #include +#include /* Limit amount of pages used for shared buffer (per domain) */ #define MAX_OPROF_SHARED_PAGES 32 @@ -577,6 +578,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN return -EPERM; } + ret = xsm_profile(current->domain, op); + if ( ret ) + return ret; + spin_lock(&xenoprof_lock); switch ( op ) diff -r 8117f6684991 -r 091fc390e6f1 xen/drivers/char/console.c --- a/xen/drivers/char/console.c Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/drivers/char/console.c Thu Mar 8 14:04:28 2007 -0500 @@ -32,6 +32,7 @@ #include #include #include +#include /* console: comma-separated list of console outputs. */ static char opt_console[30] = OPT_CONSOLE_STR; @@ -349,6 +350,10 @@ long do_console_io(int cmd, int count, X return -EPERM; #endif + rc = xsm_console_io(current->domain, cmd); + if (rc) + return rc; + switch ( cmd ) { case CONSOLEIO_write: diff -r 8117f6684991 -r 091fc390e6f1 xen/include/public/xen.h --- a/xen/include/public/xen.h Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/include/public/xen.h Thu Mar 8 14:04:28 2007 -0500 @@ -80,6 +80,7 @@ #define __HYPERVISOR_sysctl 35 #define __HYPERVISOR_domctl 36 #define __HYPERVISOR_kexec_op 37 +#define __HYPERVISOR_xsm_op 38 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff -r 8117f6684991 -r 091fc390e6f1 xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/include/xen/hypercall.h Thu Mar 8 14:04:28 2007 -0500 @@ -15,6 +15,7 @@ #include #include #include +#include extern long do_ni_hypercall( @@ -125,4 +126,9 @@ compat_memory_op( #endif +extern long +do_xsm_op( + int cmd, + XEN_GUEST_HANDLE(xsm_op_t) u_xsm_op); + #endif /* __XEN_HYPERCALL_H__ */ diff -r 8117f6684991 -r 091fc390e6f1 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Mar 7 16:21:21 2007 +0000 +++ b/xen/include/xen/sched.h Thu Mar 8 14:04:28 2007 -0500 @@ -62,6 +62,7 @@ struct evtchn u16 pirq; /* state == ECS_PIRQ */ u16 virq; /* state == ECS_VIRQ */ } u; + void *ssid; }; int evtchn_init(struct domain *d); diff -r 8117f6684991 -r 091fc390e6f1 xen/include/xsm/xsm.h --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/include/xsm/xsm.h Thu Mar 8 14:04:28 2007 -0500 @@ -0,0 +1,1033 @@ +/* + * This file contains the XSM hook definitions for Xen. + * + * This work is based on the LSM implementation in Linux 2.6.13.4. + * + * Author: George Coker, + * + * Contributors: Michael LeMay, + * + * 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 +#include + +typedef void xsm_op_t; +DEFINE_XEN_GUEST_HANDLE(xsm_op_t); + +/* policy magic number (defined by XSM_MAGIC) */ +typedef u32 xsm_magic_t; +#ifndef XSM_MAGIC +#define XSM_MAGIC 0x00000000 +#endif + +#ifdef XSM_ENABLE + +extern char *policy_buffer; +extern u32 policy_size; + +typedef int (*xsm_initcall_t)(void); + +extern xsm_initcall_t __xsm_initcall_start[], __xsm_initcall_end[]; + +#define xsm_initcall(fn) \ + static xsm_initcall_t __initcall_##fn \ + __attribute_used__ __attribute__((__section__(".xsm_initcall.init"))) = fn + +struct xsm_operations { + void (*security_domaininfo) (struct domain *d, + struct xen_domctl_getdomaininfo *info); + int (*setvcpucontext) (struct domain *d); + int (*pausedomain) (struct domain *d); + int (*unpausedomain) (struct domain *d); + int (*resumedomain) (struct domain *d); + int (*createdomain) (struct xen_domctl *op); + void (*createdomain_post) (struct domain *d, struct xen_domctl *op); + void (*createdomain_fail) (struct xen_domctl *op); + int (*max_vcpus) (struct domain *d); + int (*destroydomain) (struct domain *d); + int (*vcpuaffinity) (int cmd, struct domain *d); + int (*scheduler) (struct domain *d); + int (*getdomaininfo) (struct domain *d); + int (*getvcpucontext) (struct domain *d); + int (*getvcpuinfo) (struct domain *d); + int (*domain_settime) (struct domain *d); + int (*tbufcontrol) (void); + int (*readconsole) (uint32_t clear); + int (*sched_id) (void); + int (*setdomainmaxmem) (struct domain *d); + int (*setdomainhandle) (struct domain *d); + int (*setdebugging) (struct domain *d); + int (*irq_permission) (struct domain *d, uint8_t pirq, uint8_t access); + int (*iomem_permission) (struct domain *d, unsigned long mfn, uint8_t access); + int (*perfcontrol) (void); + + int (*shadow_control) (struct domain *d, uint32_t op); + int (*xen_settime) (void); + int (*memtype) (uint32_t access); + int (*microcode) (void); + int (*ioport_permission) (struct domain *d, uint32_t ioport, uint8_t access); + int (*physinfo) (void); + int (*getpageframeinfo) (unsigned long mfn); + int (*getmemlist) (struct domain *d); + int (*platform_quirk) (uint32_t); + int (*hypercall_init) (struct domain *d); + int (*hvmcontext) (struct domain *d, uint32_t op); + int (*address_size) (struct domain *d, uint32_t op); + + int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2); + int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1, + struct domain *d2, struct evtchn *chn2); + int (*evtchn_virq) (struct domain *d, struct evtchn *chn, int virq, int vcpu); + int (*evtchn_ipi) (struct domain *d, struct evtchn *chn, int vcpu); + int (*evtchn_pirq) (struct domain *d, struct evtchn *chn, int pirq); + int (*evtchn_close) (struct domain *d, struct evtchn *chn); + void (*evtchn_close_post) (struct evtchn *chn); + int (*evtchn_send) (struct domain *d, struct evtchn *chn); + int (*evtchn_status) (struct domain *d, struct evtchn *chn); + int (*evtchn_vcpu) (struct domain *d, struct evtchn *chn, unsigned int vcpu); + int (*evtchn_unmask) (struct domain *d, struct evtchn *chn); + int (*evtchn_reset) (struct domain *d1, struct domain *d2); + int (*evtchn_init) (struct domain *d, struct evtchn *chn); + + int (*grant_mapref) (struct domain *d1, struct domain *d2, uint32_t flags); + int (*grant_unmapref) (struct domain *d1, struct domain *d2); + int (*grant_setup) (struct domain *d1, struct domain *d2); + int (*grant_transfer) (struct domain *d1, struct domain *d2); + int (*grant_copy) (struct domain *d1, struct domain *d2); + int (*grant_query_size) (struct domain *d1, struct domain *d2); + + int (*alloc_security_domain) (struct domain *d); + void (*free_security_domain) (struct domain *d); + int (*alloc_security_evtchn) (struct evtchn *chn); + void (*free_security_evtchn) (struct evtchn *chn); + + int (*mmu_normal_update) (struct domain *d, intpte_t fpte); + int (*mmu_machphys_update) (struct domain *d, unsigned long mfn); + int (*translate_gpfn_list) (struct domain *d, unsigned long mfn); + int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2); + int (*memory_stat_reservation) (struct domain *d1, struct domain *d2); + int (*memory_pin_page) (struct domain *d, unsigned long mfn); + int (*update_va_mapping) (struct domain *d, intpte_t pte); + int (*add_to_physmap) (struct domain *d1, struct domain *d2); + int (*machine_memory_map) (void); + int (*domain_memory_map) (struct domain *d1, struct domain *d); + int (*machphys_mfn_list) (struct domain *d); + + int (*console_io) (struct domain *d, int cmd); + + int (*pirq_unmask) (struct domain *d, int pirq); + int (*pirq_status) (struct domain *d, int pirq); + int (*apic) (struct domain *d, int cmd); + int (*assign_vector) (struct domain *d, uint32_t pirq); + + int (*profile) (struct domain *d, int op); + + int (*hvm_param) (struct domain *d, unsigned long op); + int (*hvm_set_pci_intx_level) (struct domain *d); + int (*hvm_set_isa_irq_level) (struct domain *d); + int (*hvm_set_pci_link_route) (struct domain *d); + + int (*kexec) (void); + int (*schedop_shutdown) (struct domain *d1, struct domain *d2); + + long (*__do_xsm_op) (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op); + void (*complete_init) (struct domain *d); +}; + +extern struct xsm_operations *xsm_ops; + +static inline void xsm_security_domaininfo (struct domain *d, + struct xen_domctl_getdomaininfo *info) +{ + xsm_ops->security_domaininfo(d, info); +} + +static inline int xsm_setvcpucontext(struct domain *d) +{ + return xsm_ops->setvcpucontext(d); +} + +static inline int xsm_pausedomain (struct domain *d) +{ + return xsm_ops->pausedomain(d); +} + +static inline int xsm_unpausedomain (struct domain *d) +{ + return xsm_ops->unpausedomain(d); +} + +static inline int xsm_resumedomain (struct domain *d) +{ + return xsm_ops->resumedomain(d); +} + +static inline int xsm_createdomain (struct xen_domctl *op) +{ + return xsm_ops->createdomain(op); +} + +static inline void xsm_createdomain_post (struct domain *d, struct xen_domctl *op) +{ + xsm_ops->createdomain_post(d, op); +} + +static inline void xsm_createdomain_fail (struct xen_domctl *op) +{ + xsm_ops->createdomain_fail(op); +} + +static inline int xsm_max_vcpus(struct domain *d) +{ + return xsm_ops->max_vcpus(d); +} + +static inline int xsm_destroydomain (struct domain *d) +{ + return xsm_ops->destroydomain(d); +} + +static inline int xsm_vcpuaffinity (int cmd, struct domain *d) +{ + return xsm_ops->vcpuaffinity(cmd, d); +} + +static inline int xsm_scheduler (struct domain *d) +{ + return xsm_ops->scheduler(d); +} + +static inline int xsm_getdomaininfo (struct domain *d) +{ + return xsm_ops->getdomaininfo(d); +} + +static inline int xsm_getvcpucontext (struct domain *d) +{ + return xsm_ops->getvcpucontext(d); +} + +static inline int xsm_getvcpuinfo (struct domain *d) +{ + return xsm_ops->getvcpuinfo(d); +} + +static inline int xsm_domain_settime (struct domain *d) +{ + return xsm_ops->domain_settime(d); +} + +static inline int xsm_tbufcontrol (void) +{ + return xsm_ops->tbufcontrol(); +} + +static inline int xsm_readconsole (uint32_t clear) +{ + return xsm_ops->readconsole(clear); +} + +static inline int xsm_sched_id (void) +{ + return xsm_ops->sched_id(); +} + +static inline int xsm_setdomainmaxmem (struct domain *d) +{ + return xsm_ops->setdomainmaxmem(d); +} + +static inline int xsm_setdomainhandle (struct domain *d) +{ + return xsm_ops->setdomainhandle(d); +} + +static inline int xsm_setdebugging (struct domain *d) +{ + return xsm_ops->setdebugging(d); +} + +static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, uint8_t access) +{ + return xsm_ops->irq_permission(d, pirq, access); +} + +static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, uint8_t access) +{ + return xsm_ops->iomem_permission(d, mfn, access); +} + +static inline int xsm_perfcontrol (void) +{ + return xsm_ops->perfcontrol(); +} + +static inline int xsm_shadow_control (struct domain *d, uint32_t op) +{ + return xsm_ops->shadow_control(d, op); +} + +static inline int xsm_xen_settime (void) +{ + return xsm_ops->xen_settime(); +} + +static inline int xsm_memtype (uint32_t access) +{ + return xsm_ops->memtype(access); +} + +static inline int xsm_microcode (void) +{ + return xsm_ops->microcode(); +} + +static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access) +{ + return xsm_ops->ioport_permission(d, ioport, access); +} + +static inline int xsm_physinfo (void) +{ + return xsm_ops->physinfo(); +} + +static inline int xsm_getpageframeinfo (unsigned long mfn) +{ + return xsm_ops->getpageframeinfo(mfn); +} + +static inline int xsm_getmemlist (struct domain *d) +{ + return xsm_ops->getmemlist(d); +} + +static inline int xsm_platform_quirk (uint32_t quirk) +{ + return xsm_ops->platform_quirk(quirk); +} + +static inline int xsm_hypercall_init (struct domain *d) +{ + return xsm_ops->hypercall_init(d); +} + +static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd) +{ + return xsm_ops->hvmcontext(d, cmd); +} + +static inline int xsm_address_size (struct domain *d, uint32_t cmd) +{ + return xsm_ops->address_size(d, cmd); +} + +static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, + domid_t id2) +{ + return xsm_ops->evtchn_unbound(d1, chn, id2); +} + +static inline int xsm_evtchn_interdomain (struct domain *d1, struct evtchn + *chan1, struct domain *d2, struct evtchn *chan2) +{ + return xsm_ops->evtchn_interdomain(d1, chan1, d2, chan2); +} + +static inline int xsm_evtchn_virq (struct domain *d, struct evtchn *chn, + int virq, int vcpu) +{ + return xsm_ops->evtchn_virq(d, chn, virq, vcpu); +} + +static inline int xsm_evtchn_ipi (struct domain *d, struct evtchn *chn, int vcpu) +{ + return xsm_ops->evtchn_ipi(d, chn, vcpu); +} + +static inline int xsm_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq) +{ + return xsm_ops->evtchn_pirq(d, chn, pirq); +} + +static inline int xsm_evtchn_close (struct domain *d, struct evtchn *chn) +{ + return xsm_ops->evtchn_close(d, chn); +} + +static inline void xsm_evtchn_close_post (struct evtchn *chn) +{ + return xsm_ops->evtchn_close_post(chn); +} + +static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn) +{ + return xsm_ops->evtchn_send(d, chn); +} + +static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn) +{ + return xsm_ops->evtchn_status(d, chn); +} + +static inline int xsm_evtchn_vcpu (struct domain *d, struct evtchn *chn, + unsigned int vcpu) +{ + return xsm_ops->evtchn_vcpu(d, chn, vcpu); +} + +static inline int xsm_evtchn_unmask (struct domain *d, struct evtchn *chn) +{ + return xsm_ops->evtchn_unmask(d, chn); +} + +static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2) +{ + return xsm_ops->evtchn_reset(d1, d2); +} + +static inline int xsm_evtchn_init (struct domain *d, struct evtchn *chn) +{ + return xsm_ops->evtchn_init(d, chn); +} + +static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, + uint32_t flags) +{ + return xsm_ops->grant_mapref(d1, d2, flags); +} + +static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2) +{ + return xsm_ops->grant_unmapref(d1, d2); +} + +static inline int xsm_grant_setup (struct domain *d1, struct domain *d2) +{ + return xsm_ops->grant_setup(d1, d2); +} + +static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2) +{ + return xsm_ops->grant_transfer(d1, d2); +} + +static inline int xsm_grant_copy (struct domain *d1, struct domain *d2) +{ + return xsm_ops->grant_copy(d1, d2); +} + +static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2) +{ + return xsm_ops->grant_query_size(d1, d2); +} + +static inline int xsm_alloc_security_domain (struct domain *d) +{ + return xsm_ops->alloc_security_domain(d); +} + +static inline void xsm_free_security_domain (struct domain *d) +{ + xsm_ops->free_security_domain(d); +} + +static inline int xsm_alloc_security_evtchn (struct evtchn *chn) +{ + return xsm_ops->alloc_security_evtchn(chn); +} + +static inline void xsm_free_security_evtchn (struct evtchn *chn) +{ + xsm_ops->free_security_evtchn(chn); +} + +static inline int xsm_mmu_normal_update (struct domain *d, intpte_t fpte) +{ + return xsm_ops->mmu_normal_update(d, fpte); +} + +static inline int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn) +{ + return xsm_ops->mmu_machphys_update(d, mfn); +} + +static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn) +{ + return xsm_ops->translate_gpfn_list(d, mfn); +} + +static inline int xsm_memory_adjust_reservation (struct domain *d1, struct + domain *d2) +{ + return xsm_ops->memory_adjust_reservation(d1, d2); +} + +static inline int xsm_memory_stat_reservation (struct domain *d1, + struct domain *d2) +{ + return xsm_ops->memory_stat_reservation(d1, d2); +} + +static inline int xsm_memory_pin_page(struct domain *d, unsigned long mfn) +{ + return xsm_ops->memory_pin_page(d, mfn); +} + +static inline int xsm_update_va_mapping(struct domain *d, intpte_t pte) +{ + return xsm_ops->update_va_mapping(d, pte); +} + +static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) +{ + return xsm_ops->add_to_physmap(d1, d2); +} + +static inline int xsm_machine_memory_map(void) +{ + return xsm_ops->machine_memory_map(); +} + +static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2) +{ + return xsm_ops->domain_memory_map(d1, d2); +} + +static inline int xsm_machphys_mfn_list(struct domain *d) +{ + return xsm_ops->machphys_mfn_list(d); +} + +static inline int xsm_console_io (struct domain *d, int cmd) +{ + return xsm_ops->console_io(d, cmd); +} + +static inline int xsm_pirq_unmask (struct domain *d, int pirq) +{ + return xsm_ops->pirq_unmask(d, pirq); +} + +static inline int xsm_pirq_status (struct domain *d, int pirq) +{ + return xsm_ops->pirq_status(d, pirq); +} + +static inline int xsm_apic (struct domain *d, int cmd) +{ + return xsm_ops->apic(d, cmd); +} + +static inline int xsm_assign_vector (struct domain *d, uint32_t pirq) +{ + return xsm_ops->assign_vector(d, pirq); +} + +static inline int xsm_profile (struct domain *d, int op) +{ + return xsm_ops->profile(d, op); +} + +static inline int xsm_hvm_param (struct domain *d, unsigned long op) +{ + return xsm_ops->hvm_param(d, op); +} + +static inline int xsm_hvm_set_pci_intx_level (struct domain *d) +{ + return xsm_ops->hvm_set_pci_intx_level(d); +} + +static inline int xsm_hvm_set_isa_irq_level (struct domain *d) +{ + return xsm_ops->hvm_set_isa_irq_level(d); +} + +static inline int xsm_hvm_set_pci_link_route (struct domain *d) +{ + return xsm_ops->hvm_set_pci_link_route(d); +} + +static inline int xsm_kexec (void) +{ + return xsm_ops->kexec(); +} + +static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2) +{ + return xsm_ops->schedop_shutdown(d1, d2); +} + +static inline long __do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op) +{ + return xsm_ops->__do_xsm_op(cmd, op); +} + +static inline void xsm_complete_init (struct domain *d) +{ + xsm_ops->complete_init(d); +} + +extern int xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, + unsigned long initial_images_start); +extern int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi, + unsigned long initial_images_start); +extern int register_xsm(struct xsm_operations *ops); +extern int unregister_xsm(struct xsm_operations *ops); + +#else + +static inline void xsm_security_domaininfo (struct domain *d, + struct xen_domctl_getdomaininfo *info) +{ + return; +} + +static inline int xsm_setvcpucontext(struct domain *d) +{ + return 0; +} + +static inline int xsm_pausedomain (struct domain *d) +{ + return 0; +} + +static inline int xsm_unpausedomain (struct domain *d) +{ + return 0; +} + +static inline int xsm_resumedomain (struct domain *d) +{ + return 0; +} + +static inline int xsm_createdomain (struct xen_domctl *op) +{ + return 0; +} + +static inline void xsm_createdomain_post (struct domain *d, + struct xen_domctl *op) +{ + return; +} + +static inline void xsm_createdomain_fail (struct xen_domctl *op) +{ + return; +} + +static inline int xsm_max_vcpus(struct domain *d) +{ + return 0; +} + +static inline int xsm_destroydomain (struct domain *d1) +{ + return 0; +} + +static inline int xsm_vcpuaffinity (int cmd, struct domain *d) +{ + return 0; +} + +static inline int xsm_scheduler (struct domain *d) +{ + return 0; +} + +static inline int xsm_getdomaininfo (struct domain *d) +{ + return 0; +} + +static inline int xsm_getvcpucontext (struct domain *d) +{ + return 0; +} + +static inline int xsm_getvcpuinfo (struct domain *d) +{ + return 0; +} + +static inline int xsm_domain_settime (struct domain *d) +{ + return 0; +} + +static inline int xsm_tbufcontrol (void) +{ + return 0; +} + +static inline int xsm_readconsole (uint32_t clear) +{ + return 0; +} + +static inline int xsm_sched_id (void) +{ + return 0; +} + +static inline int xsm_setdomainmaxmem (struct domain *d) +{ + return 0; +} + +static inline int xsm_setdomainhandle (struct domain *d) +{ + return 0; +} + +static inline int xsm_setdebugging (struct domain *d) +{ + return 0; +} + +static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, uint8_t access) +{ + return 0; +} + +static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, uint8_t access) +{ + return 0; +} + +static inline int xsm_perfcontrol (struct domain *d) +{ + return 0; +} + +static inline int xsm_shadow_control (struct domain *d, uint32_t op) +{ + return 0; +} + +static inline int xsm_xen_settime (void) +{ + return 0; +} + +static inline int xsm_memtype (uint32_t access) +{ + return 0; +} + +static inline int xsm_microcode (void) +{ + return 0; +} + +static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, uint8_t access) +{ + return 0; +} + +static inline int xsm_physinfo (void) +{ + return 0; +} + +static inline int xsm_getpageframeinfo (unsigned long mfn) +{ + return 0; +} + +static inline int xsm_getmemlist (struct domain *d) +{ + return 0; +} + +static inline int xsm_platform_quirk (uint32_t quirk) +{ + return 0; +} + +static inline int xsm_hypercall_init (struct domain *d) +{ + return 0; +} + +static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd) +{ + return 0; +} + +static inline int xsm_address_size (struct domain *d, uint32_t cmd) +{ + return 0; +} + +static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, + domid_t id2) +{ + return 0; +} + +static inline int xsm_evtchn_interdomain (struct domain *d1, struct evtchn + *chan1, struct domain *d2, struct evtchn *chan2) +{ + return 0; +} + +static inline int xsm_evtchn_virq (struct domain *d, struct evtchn *chn, + int virq, int vcpu) +{ + return 0; +} + +static inline int xsm_evtchn_ipi (struct domain *d, struct evtchn *chn, + int vcpu) +{ + return 0; +} + +static inline int xsm_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq) +{ + return 0; +} + +static inline int xsm_evtchn_close (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static inline void xsm_evtchn_close_post (struct evtchn *chn) +{ + return; +} + +static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static inline int xsm_evtchn_vcpu (struct domain *d, struct evtchn *chn, + unsigned int vcpu) +{ + return 0; +} + +static inline int xsm_evtchn_unmask (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_evtchn_init (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, + uint32_t flags) +{ + return 0; +} + +static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_grant_setup (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_grant_copy (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_alloc_security_domain (struct domain *d) +{ + return 0; +} + +static inline void xsm_free_security_domain (struct domain *d) +{ + return; +} + +static inline int xsm_alloc_security_evtchn (struct evtchn *chn) +{ + return 0; +} + +static inline void xsm_free_security_evtchn (struct evtchn *chn) +{ + return; +} + +static inline int xsm_mmu_normal_update (struct domain *d, intpte_t fpte) +{ + return 0; +} + +static inline int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn) +{ + return 0; +} + +static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn) +{ + return 0; +} + +static inline int xsm_memory_adjust_reservation (struct domain *d1, struct + domain *d2) +{ + return 0; +} + +static inline int xsm_memory_stat_reservation (struct domain *d1, + struct domain *d2) +{ + return 0; +} + +static inline int xsm_memory_pin_page (struct domain *d, unsigned long mfn) +{ + return 0; +} + +static inline int xsm_update_va_mapping (struct domain *d, intpte_t pte) +{ + return 0; +} + +static inline int xsm_add_to_physmap (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_machine_memory_map(void) +{ + return 0; +} + +static inline int xsm_domain_memory_map(struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline int xsm_machphys_mfn_list (struct domain *d) +{ + return 0; +} + +static inline int xsm_console_io (struct domain *d, int cmd) +{ + return 0; +} + +static inline int xsm_pirq_unmask (struct domain *d, int pirq) +{ + return 0; +} + +static inline int xsm_pirq_status (struct domain *d, int pirq) +{ + return 0; +} + +static inline int xsm_apic (struct domain *d, int cmd) +{ + return 0; +} + +static inline int xsm_assign_vector (struct domain *d, uint32_t pirq) +{ + return 0; +} + +static inline int xsm_profile (struct domain *d, int op) +{ + return 0; +} + +static inline int xsm_hvm_param (struct domain *d, unsigned long op) +{ + return 0; +} + +static inline int xsm_hvm_set_pci_intx_level (struct domain *d) +{ + return 0; +} + +static inline int xsm_hvm_set_isa_irq_level (struct domain *d) +{ + return 0; +} + +static inline int xsm_hvm_set_pci_link_route (struct domain *d) +{ + return 0; +} + +static inline int xsm_kexec (void) +{ + return 0; +} + +static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static inline long __do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op) +{ + return -ENOSYS; +} + +static inline int xsm_complete_init (struct domain *d) +{ + return 0; +} + +static inline int xsm_init (unsigned int *initrdidx, const multiboot_info_t *mbi, + unsigned long initial_images_start) +{ + return 0; +} + +#endif + +#endif + +extern long do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op); diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/Makefile --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/xsm/Makefile Thu Mar 8 14:04:28 2007 -0500 @@ -0,0 +1,5 @@ +obj-y += xsm_core.o +obj-y += xsm_policy.o +ifeq ($(XSM_ENABLE),y) +obj-y += dummy.o +endif diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/dummy.c --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/xsm/dummy.c Thu Mar 8 14:04:28 2007 -0500 @@ -0,0 +1,547 @@ +/* + * This file contains the Flask hook function implementations for Xen. + * + * This work is based on the LSM implementation in Linux 2.6.13.4. + * + * Author: George Coker, + * + * Contributors: Michael LeMay, + * + * 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 +#include + +static void dummy_security_domaininfo(struct domain *d, + struct xen_domctl_getdomaininfo *info) +{ + return; +} + +static int dummy_setvcpucontext(struct domain *d) +{ + return 0; +} + +static int dummy_pausedomain (struct domain *d) +{ + return 0; +} + +static int dummy_unpausedomain (struct domain *d) +{ + return 0; +} + +static int dummy_resumedomain (struct domain *d) +{ + return 0; +} + +static int dummy_createdomain(struct xen_domctl *op) +{ + return 0; +} + +static void dummy_createdomain_post (struct domain *d, struct xen_domctl *op) +{ + return; +} + +static void dummy_createdomain_fail (struct xen_domctl *op) +{ + return; +} + +static int dummy_max_vcpus(struct domain *d) +{ + return 0; +} + +static int dummy_destroydomain (struct domain *d) +{ + return 0; +} + +static int dummy_vcpuaffinity (int cmd, struct domain *d) +{ + return 0; +} + +static int dummy_scheduler (struct domain *d) +{ + return 0; +} + +static int dummy_getdomaininfo (struct domain *d) +{ + return 0; +} + +static int dummy_getvcpucontext (struct domain *d) +{ + return 0; +} + +static int dummy_getvcpuinfo (struct domain *d) +{ + return 0; +} + +static int dummy_domain_settime (struct domain *d) +{ + return 0; +} + +static int dummy_tbufcontrol (void) +{ + return 0; +} + +static int dummy_readconsole (uint32_t clear) +{ + return 0; +} + +static int dummy_sched_id (void) +{ + return 0; +} + +static int dummy_setdomainmaxmem (struct domain *d) +{ + return 0; +} + +static int dummy_setdomainhandle (struct domain *d) +{ + return 0; +} + +static int dummy_setdebugging (struct domain *d) +{ + return 0; +} + +static int dummy_irq_permission (struct domain *d, uint8_t pirq, uint8_t access) +{ + return 0; +} + +static int dummy_iomem_permission (struct domain *d, unsigned long mfn, + uint8_t access) +{ + return 0; +} + +static int dummy_perfcontrol (void) +{ + return 0; +} + +static int dummy_shadow_control (struct domain *d, uint32_t op) +{ + return 0; +} + +static int dummy_xen_settime (void) +{ + return 0; +} + +static int dummy_memtype (uint32_t access) +{ + return 0; +} + +static int dummy_microcode (void) +{ + return 0; +} + +static int dummy_ioport_permission (struct domain *d, uint32_t ioport, + uint8_t access) +{ + return 0; +} + +static int dummy_physinfo (void) +{ + return 0; +} + +static int dummy_getpageframeinfo (unsigned long mfn) +{ + return 0; +} + +static int dummy_getmemlist (struct domain *d) +{ + return 0; +} + +static int dummy_platform_quirk (uint32_t quirk) +{ + return 0; +} + +static int dummy_hvmcontext (struct domain *d, uint32_t cmd) +{ + return 0; +} + +static int dummy_address_size (struct domain *d, uint32_t cmd) +{ + return 0; +} + +static int dummy_hypercall_init (struct domain *d) +{ + return 0; +} + +static int dummy_alloc_security_domain (struct domain *d) +{ + return 0; +} + +static void dummy_free_security_domain (struct domain *d) +{ + return; +} + +static int dummy_grant_mapref (struct domain *d1, struct domain *d2, + uint32_t flags) +{ + return 0; +} + +static int dummy_grant_unmapref (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_grant_setup (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_grant_transfer (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_grant_copy (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_grant_query_size (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_mmu_normal_update (struct domain *d, intpte_t fpte) +{ + return 0; +} + +static int dummy_mmu_machphys_update (struct domain *d, unsigned long mfn) +{ + return 0; +} + +static int dummy_translate_gpfn_list (struct domain *d, unsigned long mfn) +{ + return 0; +} + +static int dummy_memory_adjust_reservation (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_memory_stat_reservation (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_update_va_mapping (struct domain *d, intpte_t pte) +{ + return 0; +} + +static int dummy_add_to_physmap (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_machine_memory_map (void) +{ + return 0; +} + +static int dummy_domain_memory_map (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_console_io (struct domain *d, int cmd) +{ + return 0; +} + +static int dummy_pirq_unmask (struct domain *d, int pirq) +{ + return 0; +} + +static int dummy_pirq_status (struct domain *d, int pirq) +{ + return 0; +} + +static int dummy_apic (struct domain *d, int cmd) +{ + return 0; +} + +static int dummy_assign_vector (struct domain *d, uint32_t pirq) +{ + return 0; +} + +static int dummy_profile (struct domain *d, int op) +{ + return 0; +} + +static int dummy_hvm_param (struct domain *d, unsigned long op) +{ + return 0; +} + +static int dummy_hvm_set_pci_intx_level (struct domain *d) +{ + return 0; +} + +static int dummy_hvm_set_isa_irq_level (struct domain *d) +{ + return 0; +} + +static int dummy_hvm_set_pci_link_route (struct domain *d) +{ + return 0; +} + +static int dummy_kexec (void) +{ + return 0; +} + +static int dummy_schedop_shutdown (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_memory_pin_page(struct domain *d, unsigned long mfn) +{ + return 0; +} + +static int dummy_evtchn_unbound (struct domain *d, struct evtchn *chn, + domid_t id2) +{ + return 0; +} + +static int dummy_evtchn_interdomain (struct domain *d1, struct evtchn + *chan1, struct domain *d2, struct evtchn *chan2) +{ + return 0; +} + +static int dummy_evtchn_virq (struct domain *d, struct evtchn *chn, + int virq, int vcpu) +{ + return 0; +} + +static int dummy_evtchn_ipi (struct domain *d, struct evtchn *chn, int vcpu) +{ + return 0; +} + +static int dummy_evtchn_pirq (struct domain *d, struct evtchn *chn, int pirq) +{ + return 0; +} + +static int dummy_evtchn_close (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static void dummy_evtchn_close_post (struct evtchn *chn) +{ + return; +} + +static int dummy_evtchn_send (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static int dummy_evtchn_status (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static int dummy_evtchn_vcpu (struct domain *d, struct evtchn *chn, + unsigned int vcpu_id) +{ + return 0; +} + +static int dummy_evtchn_unmask (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static int dummy_alloc_security_evtchn (struct evtchn *chn) +{ + return 0; +} + +static void dummy_free_security_evtchn (struct evtchn *chn) +{ + return; +} + +static int dummy_evtchn_init (struct domain *d, struct evtchn *chn) +{ + return 0; +} + +static void dummy_complete_init (struct domain *d) +{ + return; +} + +static long dummy___do_xsm_op(int cmd, XEN_GUEST_HANDLE(xsm_op_t) op) +{ + return -ENOSYS; +} + +struct xsm_operations dummy_xsm_ops; + +#define set_to_dummy_if_null(ops, function) \ + do { \ + if (!ops->function) { \ + ops->function = dummy_##function; \ + dprintk(XENLOG_DEBUG, "Had to override the " #function \ + " security operation with the dummy one.\n"); \ + } \ + } while (0) + +void xsm_fixup_ops (struct xsm_operations *ops) +{ + set_to_dummy_if_null(ops, security_domaininfo); + set_to_dummy_if_null(ops, setvcpucontext); + set_to_dummy_if_null(ops, pausedomain); + set_to_dummy_if_null(ops, unpausedomain); + set_to_dummy_if_null(ops, resumedomain); + set_to_dummy_if_null(ops, createdomain); + set_to_dummy_if_null(ops, createdomain_post); + set_to_dummy_if_null(ops, createdomain_fail); + set_to_dummy_if_null(ops, max_vcpus); + set_to_dummy_if_null(ops, destroydomain); + set_to_dummy_if_null(ops, vcpuaffinity); + set_to_dummy_if_null(ops, scheduler); + set_to_dummy_if_null(ops, getdomaininfo); + set_to_dummy_if_null(ops, getvcpucontext); + set_to_dummy_if_null(ops, getvcpuinfo); + set_to_dummy_if_null(ops, domain_settime); + set_to_dummy_if_null(ops, tbufcontrol); + set_to_dummy_if_null(ops, readconsole); + set_to_dummy_if_null(ops, sched_id); + set_to_dummy_if_null(ops, setdomainmaxmem); + set_to_dummy_if_null(ops, setdomainhandle); + set_to_dummy_if_null(ops, setdebugging); + set_to_dummy_if_null(ops, irq_permission); + set_to_dummy_if_null(ops, iomem_permission); + set_to_dummy_if_null(ops, perfcontrol); + + set_to_dummy_if_null(ops, shadow_control); + set_to_dummy_if_null(ops, xen_settime); + set_to_dummy_if_null(ops, memtype); + set_to_dummy_if_null(ops, microcode); + set_to_dummy_if_null(ops, ioport_permission); + set_to_dummy_if_null(ops, physinfo); + set_to_dummy_if_null(ops, getpageframeinfo); + set_to_dummy_if_null(ops, getmemlist); + set_to_dummy_if_null(ops, platform_quirk); + set_to_dummy_if_null(ops, hypercall_init); + set_to_dummy_if_null(ops, hvmcontext); + set_to_dummy_if_null(ops, address_size); + + set_to_dummy_if_null(ops, evtchn_unbound); + set_to_dummy_if_null(ops, evtchn_interdomain); + set_to_dummy_if_null(ops, evtchn_virq); + set_to_dummy_if_null(ops, evtchn_pirq); + set_to_dummy_if_null(ops, evtchn_ipi); + set_to_dummy_if_null(ops, evtchn_close); + set_to_dummy_if_null(ops, evtchn_close_post); + set_to_dummy_if_null(ops, evtchn_send); + set_to_dummy_if_null(ops, evtchn_status); + set_to_dummy_if_null(ops, evtchn_vcpu); + set_to_dummy_if_null(ops, evtchn_unmask); + set_to_dummy_if_null(ops, evtchn_init); + + set_to_dummy_if_null(ops, grant_mapref); + set_to_dummy_if_null(ops, grant_unmapref); + set_to_dummy_if_null(ops, grant_setup); + set_to_dummy_if_null(ops, grant_transfer); + set_to_dummy_if_null(ops, grant_copy); + set_to_dummy_if_null(ops, grant_query_size); + + set_to_dummy_if_null(ops, alloc_security_domain); + set_to_dummy_if_null(ops, free_security_domain); + set_to_dummy_if_null(ops, alloc_security_evtchn); + set_to_dummy_if_null(ops, free_security_evtchn); + + set_to_dummy_if_null(ops, mmu_normal_update); + set_to_dummy_if_null(ops, mmu_machphys_update); + set_to_dummy_if_null(ops, translate_gpfn_list); + set_to_dummy_if_null(ops, memory_adjust_reservation); + set_to_dummy_if_null(ops, memory_stat_reservation); + set_to_dummy_if_null(ops, memory_pin_page); + set_to_dummy_if_null(ops, update_va_mapping); + set_to_dummy_if_null(ops, add_to_physmap); + set_to_dummy_if_null(ops, machine_memory_map); + set_to_dummy_if_null(ops, domain_memory_map); + + set_to_dummy_if_null(ops, console_io); + set_to_dummy_if_null(ops, pirq_unmask); + set_to_dummy_if_null(ops, pirq_status); + set_to_dummy_if_null(ops, apic); + set_to_dummy_if_null(ops, assign_vector); + + set_to_dummy_if_null(ops, profile); + + set_to_dummy_if_null(ops, hvm_param); + set_to_dummy_if_null(ops, hvm_set_pci_intx_level); + set_to_dummy_if_null(ops, hvm_set_isa_irq_level); + set_to_dummy_if_null(ops, hvm_set_pci_link_route); + + set_to_dummy_if_null(ops, kexec); + set_to_dummy_if_null(ops, schedop_shutdown); + + set_to_dummy_if_null(ops, __do_xsm_op); + set_to_dummy_if_null(ops, complete_init); +} diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/xsm_core.c --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/xsm/xsm_core.c Thu Mar 8 14:04:28 2007 -0500 @@ -0,0 +1,114 @@ +/* + * This file contains the Flask hook function implementations for Xen. + * + * This work is based on the LSM implementation in Linux 2.6.13.4. + * + * Author: George Coker, + * + * Contributors: Michael LeMay, + * + * 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 +#include +#include + +#include + +#ifdef XSM_ENABLE + +#define XSM_FRAMEWORK_VERSION "1.0.0" + +extern struct xsm_operations dummy_xsm_ops; +extern void xsm_fixup_ops(struct xsm_operations *ops); + +struct xsm_operations *xsm_ops; + +static inline int verify(struct xsm_operations *ops) +{ + /* verify the security_operations structure exists */ + if (!ops) + return -EINVAL; + xsm_fixup_ops(ops); + return 0; +} + +static void __init do_xsm_initcalls(void) +{ + xsm_initcall_t *call; + call = __xsm_initcall_start; + while (call < __xsm_initcall_end) { + (*call) (); + call++; + } +} + +int __init xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, + unsigned long initial_images_start) +{ + int ret = 0; + + printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n"); + + if (XSM_MAGIC) { + ret = xsm_policy_init(initrdidx, mbi, initial_images_start); + if (ret) { + printk("%s: Error initializing policy.\n", __FUNCTION__); + return -EINVAL; + } + } + + if (verify(&dummy_xsm_ops)) { + printk("%s could not verify " + "dummy_xsm_ops structure.\n", __FUNCTION__); + return -EIO; + } + + xsm_ops = &dummy_xsm_ops; + do_xsm_initcalls(); + + return 0; +} + +int register_xsm(struct xsm_operations *ops) +{ + if (verify(ops)) { + printk("%s could not verify " + "security_operations structure.\n", __FUNCTION__); + return -EINVAL; + } + + if (xsm_ops != &dummy_xsm_ops) + return -EAGAIN; + + xsm_ops = ops; + + return 0; +} + + +int unregister_xsm(struct xsm_operations *ops) +{ + if (ops != xsm_ops) { + printk("%s: trying to unregister " + "a security_opts structure that is not " + "registered, failing.\n", __FUNCTION__); + return -EINVAL; + } + + xsm_ops = &dummy_xsm_ops; + + return 0; +} + +#endif + +long do_xsm_op (int cmd, XEN_GUEST_HANDLE(xsm_op_t) op) +{ + return __do_xsm_op(cmd, op); +} + + diff -r 8117f6684991 -r 091fc390e6f1 xen/xsm/xsm_policy.c --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/xsm/xsm_policy.c Thu Mar 8 14:04:28 2007 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005 IBM Corporation + * + * Authors: + * Reiner Sailer, + * Stefan Berger, + * + * Contributors: + * Michael LeMay, + * George Coker, + * + * 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 +#include + +char *policy_buffer = NULL; +u32 policy_size = 0; + +int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi, + unsigned long initial_images_start) +{ + int i; + module_t *mod = (module_t *)__va(mbi->mods_addr); + int rc = 0; + char *_policy_start; + unsigned long start, _policy_len; + + /* + * Try all modules and see whichever could be the binary policy. + * Adjust the initrdidx if module[1] is the binary policy. + */ + for (i = mbi->mods_count-1; i >= 1; i--) { + start = initial_images_start + (mod[i].mod_start-mod[0].mod_start); +#if defined(__i386__) + _policy_start = (char *)start; +#elif defined(__x86_64__) + _policy_start = __va(start); +#endif + _policy_len = mod[i].mod_end - mod[i].mod_start; + + if ((xsm_magic_t)(*_policy_start) == XSM_MAGIC) { + policy_buffer = _policy_start; + policy_size = _policy_len; + + printk("Policy len 0x%lx, start at %p.\n", + _policy_len,_policy_start); + + if ( i == 1 ) + *initrdidx = (mbi->mods_count > 2) ? 2 : 0; + break; + + } + } + + return rc; +}