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