diff -r a24b5a5f5f5b -r 59ff387bd71d Config.mk --- a/Config.mk Thu Aug 31 17:14:49 2006 -0400 +++ b/Config.mk Thu Aug 31 17:45:17 2006 -0400 @@ -79,7 +79,7 @@ XSM_ENABLE ?= y # into Xen and the policy type can be set by the boot policy file # y - Build the Xen ACM framework # n - Do not build the Xen ACM framework -ACM_SECURITY ?= n +ACM_SECURITY ?= y # If ACM_SECURITY = y and no boot policy file is installed, # then the ACM defaults to the security policy set by diff -r a24b5a5f5f5b -r 59ff387bd71d linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Aug 31 17:14:49 2006 -0400 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Thu Aug 31 17:45:17 2006 -0400 @@ -263,7 +263,6 @@ static int __init privcmd_init(void) 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); diff -r a24b5a5f5f5b -r 59ff387bd71d xen/Rules.mk --- a/xen/Rules.mk Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/Rules.mk Thu Aug 31 17:45:17 2006 -0400 @@ -53,7 +53,7 @@ ALL_OBJS-y += $(BASEDIR)/a CFLAGS-y += -g -D__XEN__ CFLAGS-y += -DXSM_ENABLE -CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY +CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY -DXSM_MAGIC=0xbcde0100 CFLAGS-$(verbose) += -DVERBOSE CFLAGS-$(crash_debug) += -DCRASH_DEBUG CFLAGS-$(perfc) += -DPERF_COUNTERS diff -r a24b5a5f5f5b -r 59ff387bd71d xen/acm/Makefile --- a/xen/acm/Makefile Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/acm/Makefile Thu Aug 31 17:45:17 2006 -0400 @@ -3,3 +3,4 @@ obj-y += acm_simple_type_enforcement_hoo obj-y += acm_simple_type_enforcement_hooks.o obj-y += acm_chinesewall_hooks.o obj-y += acm_null_hooks.o +obj-y += acm_xsm_hooks.o diff -r a24b5a5f5f5b -r 59ff387bd71d xen/acm/acm_core.c --- a/xen/acm/acm_core.c Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/acm/acm_core.c Thu Aug 31 17:45:17 2006 -0400 @@ -31,6 +31,7 @@ #include #include #include +#include /* debug: * include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE; @@ -48,6 +49,8 @@ void acm_init_ste_policy(void); extern struct acm_operations acm_chinesewall_ops, acm_simple_type_enforcement_ops, acm_null_ops; + +extern struct xsm_operations acm_xsm_ops; /* global ACM policy (now dynamically determined at boot time) */ u16 acm_active_security_policy = ACM_POLICY_UNDEFINED; @@ -158,84 +161,15 @@ acm_init_binary_policy(u32 policy_code) return ret; } -static int -acm_setup(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 = ACM_OK; - - 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--) - { - struct acm_policy_buffer *pol; - char *_policy_start; - unsigned long _policy_len; -#if defined(__i386__) - _policy_start = (char *)(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 sHype -#endif - _policy_len = mod[i].mod_end - mod[i].mod_start; - if (_policy_len < sizeof(struct acm_policy_buffer)) - continue; /* not a policy */ - - pol = (struct acm_policy_buffer *)_policy_start; - if (ntohl(pol->magic) == ACM_MAGIC) - { - rc = acm_set_policy((void *)_policy_start, - (u32)_policy_len, - 0); - if (rc == ACM_OK) - { - printf("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; - } - else - { - printk("Invalid policy. %d.th module line.\n", i+1); - } - } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */ - } - return rc; -} - - -int -acm_init(unsigned int *initrdidx, - const multiboot_info_t *mbi, - unsigned long initial_images_start) +static __init int acm_init(void) { int ret = ACM_OK; + printk("ACM-XSM: Initializing.\n"); + acm_set_endian(); - /* first try to load the boot policy (uses its own locks) */ - acm_setup(initrdidx, mbi, initial_images_start); + acm_set_policy(policy_buffer, policy_size, 0); if (acm_active_security_policy != ACM_POLICY_UNDEFINED) { @@ -262,8 +196,14 @@ acm_init(unsigned int *initrdidx, /* here one could imagine a clean panic */ return -EINVAL; } + + if (register_xsm(&acm_xsm_ops)) + panic("ACM-XSM: Unable to register with XSM.\n"); + return ret; } + +xsm_initcall(acm_init); int acm_init_domain_ssid(domid_t id, ssidref_t ssidref) diff -r a24b5a5f5f5b -r 59ff387bd71d xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/arch/x86/setup.c Thu Aug 31 17:45:17 2006 -0400 @@ -23,7 +23,6 @@ #include #include #include -#include #include extern void dmi_scan_machine(void); @@ -499,17 +498,12 @@ void __init __start_xen(multiboot_info_t shadow_mode_init(); - /* initialize access control security module */ - acm_init(&initrdidx, mbi, initial_images_start); - /* Create initial domain 0. */ dom0 = domain_create(0, 0); if ( dom0 == NULL ) panic("Error creating domain 0\n"); set_bit(_DOMF_privileged, &dom0->domain_flags); - /* post-create hooks sets security label */ - acm_post_domain0_create(dom0->domain_id); xsm_complete_init(dom0); diff -r a24b5a5f5f5b -r 59ff387bd71d xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/arch/x86/x86_32/entry.S Thu Aug 31 17:45:17 2006 -0400 @@ -645,10 +645,9 @@ ENTRY(hypercall_table) .long do_vcpu_op .long do_ni_hypercall /* 25 */ .long do_mmuext_op - .long do_acm_op + .long do_xsm_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 @@ -681,10 +680,9 @@ ENTRY(hypercall_args_table) .byte 3 /* do_vcpu_op */ .byte 0 /* do_ni_hypercall */ /* 25 */ .byte 4 /* do_mmuext_op */ - .byte 1 /* do_acm_op */ + .byte 1 /* do_xsm_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 a24b5a5f5f5b -r 59ff387bd71d xen/common/dom0_ops.c --- a/xen/common/dom0_ops.c Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/common/dom0_ops.c Thu Aug 31 17:45:17 2006 -0400 @@ -21,7 +21,6 @@ #include #include #include -#include #include extern long arch_do_dom0_op( @@ -79,11 +78,6 @@ static void getdomaininfo(struct domain ((d->domain_flags & DOMF_ctrl_pause) ? DOMFLAGS_PAUSED : 0) | d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; - if (d->ssid != NULL) - 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; @@ -97,7 +91,6 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) { long ret = 0; struct dom0_op curop, *op = &curop; - void *ssid = NULL; /* save security ptr between pre and post/fail hooks */ static spinlock_t dom0_lock = SPIN_LOCK_UNLOCKED; if ( !IS_PRIV(current->domain) ) @@ -108,9 +101,6 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) if ( op->interface_version != DOM0_INTERFACE_VERSION ) return -EACCES; - - if ( acm_pre_dom0_op(op, &ssid) ) - return -EPERM; spin_lock(&dom0_lock); @@ -820,11 +810,6 @@ long do_dom0_op(GUEST_HANDLE(dom0_op_t) spin_unlock(&dom0_lock); - if (!ret) - acm_post_dom0_op(op, ssid); - else - acm_fail_dom0_op(op, ssid); - return ret; } diff -r a24b5a5f5f5b -r 59ff387bd71d xen/common/event_channel.c --- a/xen/common/event_channel.c Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/common/event_channel.c Thu Aug 31 17:45:17 2006 -0400 @@ -28,7 +28,6 @@ #include #include -#include #include #define bucket_from_port(d,p) \ @@ -686,9 +685,6 @@ long do_event_channel_op(GUEST_HANDLE(ev if ( copy_from_guest(&op, uop, 1) != 0 ) return -EFAULT; - if (acm_pre_event_channel(&op)) - return -EACCES; - switch ( op.cmd ) { case EVTCHNOP_alloc_unbound: diff -r a24b5a5f5f5b -r 59ff387bd71d xen/common/grant_table.c --- a/xen/common/grant_table.c Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/common/grant_table.c Thu Aug 31 17:45:17 2006 -0400 @@ -30,7 +30,6 @@ #include #include #include -#include #include #define PIN_FAIL(_lbl, _rc, _f, _a...) \ @@ -102,12 +101,6 @@ __gnttab_map_grant_ref( { DPRINTK("Bad ref (%d) or flags (%x).\n", op->ref, op->flags); op->status = GNTST_bad_gntref; - return; - } - - if ( acm_pre_grant_map_ref(op->dom) ) - { - op->status = GNTST_permission_denied; return; } diff -r a24b5a5f5f5b -r 59ff387bd71d xen/include/acm/acm_hooks.h --- a/xen/include/acm/acm_hooks.h Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/include/acm/acm_hooks.h Thu Aug 31 17:45:17 2006 -0400 @@ -373,10 +373,6 @@ static inline int acm_sharing(ssidref_t return ACM_ACCESS_PERMITTED; } -extern int acm_init(unsigned int *initrdidx, - const multiboot_info_t *mbi, - unsigned long start); - #endif #endif diff -r a24b5a5f5f5b -r 59ff387bd71d xen/include/public/acm.h --- a/xen/include/public/acm.h Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/include/public/acm.h Thu Aug 31 17:45:17 2006 -0400 @@ -110,8 +110,8 @@ typedef uint16_t domaintype_t; * tools that assume packed representations (e.g. the java tool) */ struct acm_policy_buffer { + uint32_t magic; uint32_t policy_version; /* ACM_POLICY_VERSION */ - uint32_t magic; uint32_t len; uint32_t primary_policy_code; uint32_t primary_buffer_offset; diff -r a24b5a5f5f5b -r 59ff387bd71d xen/include/public/xen.h --- a/xen/include/public/xen.h Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/include/public/xen.h Thu Aug 31 17:45:17 2006 -0400 @@ -57,10 +57,9 @@ #define __HYPERVISOR_vcpu_op 24 #define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ #define __HYPERVISOR_mmuext_op 26 -#define __HYPERVISOR_acm_op 27 +#define __HYPERVISOR_xsm_op 27 #define __HYPERVISOR_nmi_op 28 #define __HYPERVISOR_sched_op 29 -#define __HYPERVISOR_xsm_op 30 /* * VIRTUAL INTERRUPTS diff -r a24b5a5f5f5b -r 59ff387bd71d xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h Thu Aug 31 17:14:49 2006 -0400 +++ b/xen/include/xen/hypercall.h Thu Aug 31 17:45:17 2006 -0400 @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -79,10 +78,6 @@ do_vcpu_op( GUEST_HANDLE(void) arg); extern long -do_acm_op( - GUEST_HANDLE(acm_op_t) u_acm_op); - -extern long do_xsm_op( GUEST_HANDLE(xsm_op_t) u_xsm_op); diff -r a24b5a5f5f5b -r 59ff387bd71d xen/acm/acm_xsm_hooks.c --- /dev/null Thu Jan 1 00:00:00 1970 +0000 +++ b/xen/acm/acm_xsm_hooks.c Thu Aug 31 17:45:17 2006 -0400 @@ -0,0 +1,195 @@ +/**************************************************************** + * acm_xsm_hooks.c + * + * Copyright (C) 2005 IBM Corporation + * + * Author: + * Reiner Sailer + * + * Contributors: + * Michael LeMay, + * George Coker, + * + * sHype hooks for XSM based on the original ACM hooks. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ + +#include +#include +#include + +static int acm_createdomain (dom0_op_t *op) +{ + void *subject_ssid = current->domain->ssid; + ssidref_t ssidref = op->u.createdomain.ssidref; + + if ((acm_primary_ops->pre_domain_create != NULL) && + acm_primary_ops->pre_domain_create(subject_ssid, ssidref)) + return ACM_ACCESS_DENIED; + else if ((acm_secondary_ops->pre_domain_create != NULL) && + acm_secondary_ops->pre_domain_create(subject_ssid, ssidref)) { + /* roll-back primary */ + if (acm_primary_ops->fail_domain_create != NULL) + acm_primary_ops->fail_domain_create(subject_ssid, ssidref); + return ACM_ACCESS_DENIED; + } else + return ACM_ACCESS_PERMITTED; +} + +static void acm_createdomain_post (struct domain *d, dom0_op_t *op) +{ + ssidref_t ssidref = op->u.createdomain.ssidref; + + /* initialialize shared sHype security labels for new domain */ + acm_init_domain_ssid(d->domain_id, ssidref); + + if (acm_primary_ops->post_domain_create != NULL) + acm_primary_ops->post_domain_create(d->domain_id, ssidref); + if (acm_secondary_ops->post_domain_create != NULL) + acm_secondary_ops->post_domain_create(d->domain_id, ssidref); +} + +static int acm_destroydomain (struct domain *d) +{ + int ret = -EACCES; + void *ssid = NULL; + + if (d != NULL) { + ssid = d->ssid; + + if (ssid == NULL) { + printk("%s: Warning. Destroying domain without ssid pointer.\n", __func__); + return -EACCES; + } + + ret = 0; + } + + return ret; +} + +static void acm_destroydomain_post (struct domain *d) +{ + domid_t id = d->domain_id; + + if (acm_primary_ops->post_domain_destroy != NULL) + acm_primary_ops->post_domain_destroy(d->ssid, id); + if (acm_secondary_ops->post_domain_destroy != NULL) + acm_secondary_ops->post_domain_destroy(d->ssid, id); + + /* free security ssid for the destroyed domain (also if null policy */ + acm_free_domain_ssid((struct acm_ssid_domain *)(d->ssid)); + d->ssid = NULL; +} + +static void acm_createdomain_fail (dom0_op_t *op) +{ + acm_fail_domain_create( + current->domain->ssid, op->u.createdomain.ssidref); +} + +static int acm_grant_mapref (struct domain *ld, struct domain *rd, + uint32_t flags) +{ + domid_t id = rd->domain_id; + + if ( (acm_primary_ops->pre_grant_map_ref != NULL) && + acm_primary_ops->pre_grant_map_ref(id) ) + { + return ACM_ACCESS_DENIED; + } + else if ( (acm_secondary_ops->pre_grant_map_ref != NULL) && + acm_secondary_ops->pre_grant_map_ref(id) ) + { + /* roll-back primary */ + if ( acm_primary_ops->fail_grant_map_ref != NULL ) + acm_primary_ops->fail_grant_map_ref(id); + return ACM_ACCESS_DENIED; + } + else + { + return ACM_ACCESS_PERMITTED; + } +} + +static int acm_evtchn_unbound (struct domain *d1, struct evtchn *chn1, domid_t id2) +{ + domid_t id1 = d1->domain_id; + + if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && + acm_primary_ops->pre_eventchannel_unbound(id1, id2)) + return ACM_ACCESS_DENIED; + else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && + acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) { + /* roll-back primary */ + if (acm_primary_ops->fail_eventchannel_unbound != NULL) + acm_primary_ops->fail_eventchannel_unbound(id1, id2); + return ACM_ACCESS_DENIED; + } else + return ACM_ACCESS_PERMITTED; +} + +static int acm_evtchn_interdomain (struct domain *d1, struct evtchn *chn1, + struct domain *d2, struct evtchn *chn2) +{ + domid_t id2 = d2->domain_id; + + if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) && + acm_primary_ops->pre_eventchannel_interdomain(id2)) + return ACM_ACCESS_DENIED; + else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) && + acm_secondary_ops->pre_eventchannel_interdomain(id2)) { + /* roll-back primary */ + if (acm_primary_ops->fail_eventchannel_interdomain != NULL) + acm_primary_ops->fail_eventchannel_interdomain(id2); + return ACM_ACCESS_DENIED; + } else + return ACM_ACCESS_PERMITTED; +} + +static void acm_complete_init (struct domain *dom0) +{ + domid_t domid = dom0->domain_id; + + acm_init_domain_ssid(domid, ACM_DOM0_SSIDREF); + + if (acm_primary_ops->post_domain_create != NULL) + acm_primary_ops->post_domain_create(domid, ACM_DOM0_SSIDREF); + if (acm_secondary_ops->post_domain_create != NULL) + acm_secondary_ops->post_domain_create(domid, ACM_DOM0_SSIDREF); + +} + +static void acm_security_domaininfo (struct domain *d, dom0_getdomaininfo_t *info) +{ + if (d->ssid != NULL) + info->ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref; + else + info->ssidref = ACM_DEFAULT_SSID; +} + +extern long do_acm_op(GUEST_HANDLE(xsm_op_t) u_acm_op); + +struct xsm_operations acm_xsm_ops = { + .createdomain = acm_createdomain, + .createdomain_post = acm_createdomain_post, + .createdomain_fail = acm_createdomain_fail, + .destroydomain = acm_destroydomain, + .free_security_domain = acm_destroydomain_post, + + .grant_mapref = acm_grant_mapref, + + .evtchn_unbound = acm_evtchn_unbound, + .evtchn_interdomain = acm_evtchn_interdomain, + .complete_init = acm_complete_init, + + .security_domaininfo = acm_security_domaininfo, + + .__do_xsm_op = do_acm_op, +}; +