[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel][Xense-devel][PATCH][1/4] Xen Security Modules - XSM Framework



* George S. Coker, II (gscoker@xxxxxxxxxxxxxx) wrote:
> - Updated for tip, 15730:256160ff19b7
> 
> Signed-off-by: George Coker <gscoker@xxxxxxxxxxxxxx>


> diff -r 256160ff19b7 -r bc357f5fe8cc Config.mk
> --- a/Config.mk       Thu Aug 16 13:27:59 2007 +0100
> +++ b/Config.mk       Wed Aug 22 16:26:21 2007 -0400
> @@ -75,6 +75,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 ?= n
> +
>  # 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 256160ff19b7 -r bc357f5fe8cc xen/Makefile
> --- a/xen/Makefile    Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/Makefile    Wed Aug 22 16:26:21 2007 -0400
> @@ -56,6 +56,7 @@ _clean: delete-unfresh-files
>       $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
>       $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
>       $(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
> +     $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
>       $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
>       rm -f include/asm *.o $(TARGET)* *~ core
>       rm -f include/asm-*/asm-offsets.h
> @@ -122,7 +123,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 256160ff19b7 -r bc357f5fe8cc xen/Rules.mk
> --- a/xen/Rules.mk    Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/Rules.mk    Wed Aug 22 16:26:21 2007 -0400
> @@ -52,10 +52,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 256160ff19b7 -r bc357f5fe8cc xen/arch/x86/domctl.c
> --- a/xen/arch/x86/domctl.c   Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/arch/x86/domctl.c   Wed Aug 22 16:26:21 2007 -0400
> @@ -24,6 +24,7 @@
>  #include <asm/hvm/hvm.h>
>  #include <asm/hvm/support.h>
>  #include <asm/processor.h>
> +#include <xsm/xsm.h>
>  
>  long arch_do_domctl(
>      struct xen_domctl *domctl,
> @@ -41,6 +42,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));

Any reason not to put this in paging_domctl, after some of its error
checking?

> @@ -63,6 +71,14 @@ 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;
> @@ -87,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);

Should this check be here, and pass page?

> @@ -171,6 +194,10 @@ long arch_do_domctl(
>                  struct page_info *page;
>                  unsigned long mfn = arr32[j];
>  
> +                ret = xsm_getpageframeinfo(mfn);
> +                if ( ret )
> +                    continue;
> +
>                  page = mfn_to_page(mfn);

Same here.

>                  if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 

> diff -r 256160ff19b7 -r bc357f5fe8cc xen/arch/x86/hvm/hvm.c
> --- a/xen/arch/x86/hvm/hvm.c  Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/arch/x86/hvm/hvm.c  Wed Aug 22 16:26:21 2007 -0400
> @@ -1,3 +1,4 @@
> +

Extra whitespace.

>  /*
>   * hvm.c: Common hardware virtual machine abstractions.
>   *
> @@ -1068,6 +1069,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;
> +

Should IS_PRIV be handled here instead of a separate call?
Also, I'd think it could be after is_hvm_domain (same with hvmcontext
calls).

>      rc = -EINVAL;
>      if ( !is_hvm_domain(d) )
>          goto out;
> @@ -1111,6 +1116,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;
> +

Same here

>      rc = -EINVAL;
>      if ( !is_hvm_domain(d) )
>          goto out;
> @@ -1153,6 +1162,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;

and here

>  
>      rc = -EINVAL;
>      if ( !is_hvm_domain(d) )
> @@ -1196,6 +1209,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;

and here (although IS_PRIV handling a bit different here)

> --- a/xen/arch/x86/mm.c       Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/arch/x86/mm.c       Wed Aug 22 16:26:21 2007 -0400
> @@ -110,6 +110,7 @@
>  #include <asm/hypercall.h>
>  #include <asm/shared.h>
>  #include <public/memory.h>
> +#include <xsm/xsm.h>
>  
>  #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
>  
> @@ -2046,6 +2047,10 @@ int do_mmuext_op(
>              type = PGT_l4_page_table;
>  
>          pin_page:
> +            rc = xsm_memory_pin_page(current->domain, mfn);
> +            if ( rc )
> +                break;
> +

Why not pass page?

>              /* Ignore pinning of invalid paging levels. */
>              if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) 
> )
>                  break;
> @@ -2331,6 +2336,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;

biglock is still held

>  
>              gmfn = req.ptr >> PAGE_SHIFT;
>              mfn = gmfn_to_mfn(d, gmfn);
> @@ -2422,6 +2431,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;
> +

same here

>              if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) )
>              {
>                  MEM_LOG("Could not get page for mach->phys update");
> @@ -2800,6 +2813,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);
> +    if ( rc )
> +        return rc;
> +
>      LOCK_BIGLOCK(d);
>  
>      pl1e = guest_map_l1e(v, va, &gl1mfn);
> @@ -3061,6 +3078,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);

rcu_unlock_domain shouldn't be conditional

> +            return -EPERM;
> +        }
> +
>          switch ( xatp.space )
>          {
>          case XENMAPSPACE_shared_info:
> @@ -3170,9 +3194,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;

Collapse IS_PRIV?

>          if ( copy_from_guest(&memmap, arg, 1) )
>              return -EFAULT;

set_memory_map?

> diff -r 256160ff19b7 -r bc357f5fe8cc xen/arch/x86/physdev.c
> --- a/xen/arch/x86/physdev.c  Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/arch/x86/physdev.c  Wed Aug 22 16:26:21 2007 -0400
> @@ -12,6 +12,7 @@
>  #include <asm/hypercall.h>
>  #include <public/xen.h>
>  #include <public/physdev.h>
> +#include <xsm/xsm.h>
>  
>  #ifndef COMPAT
>  typedef long ret_t;
> @@ -73,6 +74,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
>          ret = -EPERM;
>          if ( !IS_PRIV(v->domain) )
>              break;
> +        ret = xsm_apic(current->domain, cmd);
> +        if ( ret )
> +            break;

IS_PRIV, and use v instead of current

>          ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
>          if ( copy_to_guest(arg, &apic, 1) != 0 )
>              ret = -EFAULT;
> @@ -87,6 +91,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
>          ret = -EPERM;
>          if ( !IS_PRIV(v->domain) )
>              break;
> +        ret = xsm_apic(current->domain, cmd);
> +        if ( ret )
> +            break;

IS_PRIV and use v instead of current

>          ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
>          break;
>      }
> @@ -100,6 +107,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
>  
>          ret = -EPERM;
>          if ( !IS_PRIV(v->domain) )
> +            break;
> +
> +        ret = xsm_assign_vector(current->domain, irq_op.irq);
> +        if ( ret )
>              break;

same here

>  
>          irq = irq_op.irq;
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/arch/x86/platform_hypercall.c
> --- a/xen/arch/x86/platform_hypercall.c       Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/arch/x86/platform_hypercall.c       Wed Aug 22 16:26:21 2007 -0400
> @@ -120,6 +137,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);

Doesn't build on x86_64

> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/domain.c
> --- a/xen/common/domain.c     Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/domain.c     Wed Aug 22 16:26:21 2007 -0400
> @@ -29,6 +29,7 @@
>  #include <public/sched.h>
>  #include <public/vcpu.h>
>  #include <acm/acm_hooks.h>
> +#include <xsm/xsm.h>
>  
>  /* Protect updates/reads (resp.) of domain_list and domain_hash. */
>  DEFINE_SPINLOCK(domlist_update_lock);
> @@ -57,6 +58,13 @@ struct domain *alloc_domain(domid_t domi
>  
>      memset(d, 0, sizeof(*d));
>      d->domain_id = domid;
> +
> +    if ( xsm_alloc_security_domain(d) != 0 )
> +    {
> +        free_domain(d);

xfree?

> +        return NULL;
> +    }
> +
>      atomic_set(&d->refcnt, 1);
>      spin_lock_init(&d->big_lock);
>      spin_lock_init(&d->page_alloc_lock);
> @@ -69,6 +77,7 @@ struct domain *alloc_domain(domid_t domi
>  
>  void free_domain(struct domain *d)
>  {
> +    xsm_free_security_domain(d);
>      xfree(d);
>  }
>  
> @@ -193,6 +202,9 @@ struct domain *domain_create(
>  
>      if ( !is_idle_domain(d) )
>      {
> +        if ( xsm_domain_create(d, ssidref) != 0 )
> +            goto fail;
> +
>          d->is_paused_by_controller = 1;
>          atomic_inc(&d->pause_count);
>  
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/domctl.c
> --- a/xen/common/domctl.c     Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/domctl.c     Wed Aug 22 16:26:21 2007 -0400
> @@ -24,6 +24,7 @@
>  #include <asm/current.h>
>  #include <public/domctl.h>
>  #include <acm/acm_hooks.h>
> +#include <xsm/xsm.h>
>  
>  extern long arch_do_domctl(
>      struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
> @@ -127,7 +128,9 @@ 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;
>      info->shared_info_frame = mfn_to_gmfn(d, 
> __pa(d->shared_info)>>PAGE_SHIFT);
> @@ -204,6 +207,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>          if ( d == NULL )
>              break;
>  
> +        ret = xsm_setvcpucontext(d);
> +        if ( ret )
> +        {
> +            rcu_unlock_domain(d);
> +            break;

just use goto svc_out like others?

> +        }
> +
>          ret = -EINVAL;
>          if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
>              goto svc_out;
> @@ -251,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);
>          }
>      }
> @@ -270,7 +285,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>          if ( d == NULL )
>              break;
>  
> +        ret = xsm_unpausedomain(d);
> +        if ( ret )
> +            goto unpausedomain_out;
> +
>          domain_unpause_by_systemcontroller(d);
> +
> +    unpausedomain_out:
>          rcu_unlock_domain(d);
>          ret = 0;

lost error return value

>      }
> @@ -283,6 +304,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>          ret = -ESRCH;
>          if ( d == NULL )
>              break;
> +
> +        ret = xsm_resumedomain(d);
> +        if ( ret )
> +        {
> +            rcu_unlock_domain(d);
> +            break;
> +        }
>  
>          domain_resume(d);
>          rcu_unlock_domain(d);
> @@ -359,6 +387,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>          if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
>              break;
>  
> +        ret = xsm_max_vcpus(d);
> +        if ( ret )
> +        {
> +            rcu_unlock_domain(d);
> +            break;
> +        }
> +
>          /* Needed, for example, to ensure writable p.t. state is synced. */
>          domain_pause(d);
>  
> @@ -395,12 +430,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>          ret = -ESRCH;
>          if ( d != NULL )
>          {
> +            ret = xsm_destroydomain(d);
> +            if ( ret )
> +                goto destroydomain_out;
> +
>              ret = -EINVAL;
>              if ( d != current->domain )
>              {
>                  domain_kill(d);
>                  ret = 0;
>              }
> +
> +        destroydomain_out:
>              rcu_unlock_domain(d);
>          }
>      }
> @@ -418,6 +459,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;
> @@ -452,10 +497,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;
> @@ -478,12 +528,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
>              break;
>          }
>  
> +        ret = xsm_getdomaininfo(d);
> +        if ( ret )
> +            goto getdomaininfo_out;
> +

can use this new goto in d == NULL cleanup

>          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;
> @@ -497,6 +552,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;
> +        }

can goto getvcpucontext_out

>          ret = -EINVAL;
>          if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/kexec.c
> --- a/xen/common/kexec.c      Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/kexec.c      Wed Aug 22 16:26:21 2007 -0400
> @@ -21,6 +21,7 @@
>  #include <xen/version.h>
>  #include <xen/console.h>
>  #include <public/elfnote.h>
> +#include <xsm/xsm.h>
>  
>  #ifndef COMPAT
>  
> @@ -367,6 +368,10 @@ ret_t do_kexec_op(unsigned long op, XEN_
>      if ( !IS_PRIV(current->domain) )
>          return -EPERM;
>  
> +    ret = xsm_kexec();
> +    if ( ret )
> +        return ret;
> +

IS_PRIV collapse?

>      switch ( op )
>      {
>      case KEXEC_CMD_kexec_get_range:
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/memory.c
> --- a/xen/common/memory.c     Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/memory.c     Wed Aug 22 16:26:21 2007 -0400
> @@ -22,6 +22,7 @@
>  #include <asm/current.h>
>  #include <asm/hardirq.h>
>  #include <public/memory.h>
> +#include <xsm/xsm.h>
>  
>  struct memop_args {
>      /* INPUT */
> @@ -216,6 +217,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;
> @@ -258,6 +260,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;
> +        }

IS_PRIV?

>          if ( unlikely(__copy_to_guest_offset(op.mfn_list, i, &mfn, 1)) )
>          {
> @@ -538,6 +547,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:
> @@ -583,6 +600,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;
> +        }
>  
>          switch ( op )
>          {
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/schedule.c
> --- a/xen/common/schedule.c   Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/schedule.c   Wed Aug 22 16:26:21 2007 -0400
> @@ -32,6 +32,7 @@
>  #include <xen/guest_access.h>
>  #include <xen/multicall.h>
>  #include <public/sched.h>
> +#include <xsm/xsm.h>
>  
>  /* opt_sched: scheduler - default to credit */
>  static char opt_sched[10] = "credit";
> @@ -460,6 +461,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_pause() prevens any further execution in guest context. */
>          domain_pause(d);
> diff -r 256160ff19b7 -r bc357f5fe8cc xen/common/sysctl.c
> --- a/xen/common/sysctl.c     Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/sysctl.c     Wed Aug 22 16:26:21 2007 -0400
> @@ -23,6 +23,7 @@
>  #include <public/sysctl.h>
>  #include <asm/numa.h>
>  #include <xen/nodemask.h>
> +#include <xsm/xsm.h>
>  
>  extern long arch_do_sysctl(
>      struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
> @@ -48,6 +49,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,
> @@ -59,6 +64,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;
> @@ -67,6 +76,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;
> @@ -90,6 +103,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,
> @@ -117,6 +134,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 256160ff19b7 -r bc357f5fe8cc xen/common/xenoprof.c
> --- a/xen/common/xenoprof.c   Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/common/xenoprof.c   Wed Aug 22 16:26:21 2007 -0400
> @@ -14,6 +14,7 @@
>  #include <xen/sched.h>
>  #include <public/xenoprof.h>
>  #include <xen/paging.h>
> +#include <xsm/xsm.h>
>  
>  /* Limit amount of pages used for shared buffer (per domain) */
>  #define MAX_OPROF_SHARED_PAGES 32
> @@ -634,6 +635,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 256160ff19b7 -r bc357f5fe8cc xen/drivers/char/console.c
> --- a/xen/drivers/char/console.c      Thu Aug 16 13:27:59 2007 +0100
> +++ b/xen/drivers/char/console.c      Wed Aug 22 16:26:21 2007 -0400
> @@ -32,6 +32,7 @@
>  #include <asm/debugger.h>
>  #include <asm/io.h>
>  #include <asm/div64.h>
> +#include <xsm/xsm.h>
>  
>  /* console: comma-separated list of console outputs. */
>  static char opt_console[30] = OPT_CONSOLE_STR;
> @@ -357,6 +358,10 @@ long do_console_io(int cmd, int count, X
>      if ( current->domain->domain_id != 0 )
>          return -EPERM;
>  #endif
> +
> +    rc = xsm_console_io(current->domain, cmd);
> +    if ( rc )
> +        return rc;
>  
>      switch ( cmd )
>      {
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/xen/include/xsm/xsm.h   Wed Aug 22 16:26:21 2007 -0400
> @@ -0,0 +1,537 @@
> +/*
> + *  This file contains the XSM hook definitions for Xen.
> + *
> + *  This work is based on the LSM implementation in Linux 2.6.13.4.
> + *
> + *  Author:  George Coker, <gscoker@xxxxxxxxxxxxxx>
> + *
> + *  Contributors: Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2,
> + *  as published by the Free Software Foundation.
> + */
> +
> +#ifndef __XSM_H__
> +#define __XSM_H__
> +
> +#include <xen/sched.h>
> +#include <xen/multiboot.h>
> +
> +typedef void xsm_op_t;
> +DEFINE_XEN_GUEST_HANDLE(xsm_op_t);
> +
> +extern long do_xsm_op (XEN_GUEST_HANDLE(xsm_op_t) op);
> +
> +#ifdef XSM_ENABLE
> +    #define xsm_call(fn) xsm_ops->fn
> +#else
> +    #define xsm_call(fn) 0
> +#endif
> +
> +/* 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
> +

This could benefit from some comments re: usage for each hook.

> +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 (*domain_create) (struct domain *d, u32 ssidref);
> +    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 (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t 
> id2);
> +    int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
> +                                        struct domain *d2, struct evtchn 
> *chn2);
> +    void (*evtchn_close_post) (struct evtchn *chn);
> +    int (*evtchn_send) (struct domain *d, struct evtchn *chn);
> +    int (*evtchn_status) (struct domain *d, struct evtchn *chn);
> +    int (*evtchn_reset) (struct domain *d1, struct domain *d2);
> +
> +    int (*grant_mapref) (struct domain *d1, struct domain *d2, uint32_t 
> flags);
> +    int (*grant_unmapref) (struct domain *d1, struct domain *d2);
> +    int (*grant_setup) (struct domain *d1, struct domain *d2);
> +    int (*grant_transfer) (struct domain *d1, struct domain *d2);
> +    int (*grant_copy) (struct domain *d1, struct domain *d2);
> +    int (*grant_query_size) (struct domain *d1, struct domain *d2);
> +
> +    int (*alloc_security_domain) (struct domain *d);
> +    void (*free_security_domain) (struct domain *d);
> +    int (*alloc_security_evtchn) (struct evtchn *chn);
> +    void (*free_security_evtchn) (struct evtchn *chn);
> +
> +    int (*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, l1_pgentry_t pte);
> +
> +    int (*console_io) (struct domain *d, int cmd);
> +
> +    int (*profile) (struct domain *d, int op);
> +
> +    int (*kexec) (void);
> +    int (*schedop_shutdown) (struct domain *d1, struct domain *d2);
> +
> +    long (*__do_xsm_op) (XEN_GUEST_HANDLE(xsm_op_t) op);
> +    void (*complete_init) (struct domain *d);
> +
> +#ifdef CONFIG_X86
> +    int (*shadow_control) (struct domain *d, uint32_t op);
> +    int (*ioport_permission) (struct domain *d, uint32_t ioport, 
> +                                                                uint8_t 
> access);
> +    int (*getpageframeinfo) (unsigned long mfn);
> +    int (*getmemlist) (struct domain *d);
> +    int (*hypercall_init) (struct domain *d);
> +    int (*hvmcontext) (struct domain *d, uint32_t op);
> +    int (*address_size) (struct domain *d, uint32_t 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 (*apic) (struct domain *d, int cmd);
> +    int (*assign_vector) (struct domain *d, uint32_t pirq);
> +    int (*xen_settime) (void);
> +    int (*memtype) (uint32_t access);
> +    int (*microcode) (void);
> +    int (*physinfo) (void);
> +    int (*platform_quirk) (uint32_t);
> +    int (*machine_memory_map) (void);
> +    int (*domain_memory_map) (struct domain *d1, struct domain *d);
> +    int (*mmu_normal_update) (struct domain *d, intpte_t fpte);
> +    int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
> +    int (*add_to_physmap) (struct domain *d1, struct domain *d2);
> +#endif
> +};
> +
> +#endif
> +
> +extern struct xsm_operations *xsm_ops;
> +++ b/xen/xsm/dummy.c Wed Aug 22 16:26:21 2007 -0400
> @@ -0,0 +1,490 @@
> +/*
> + *  This file contains the Flask hook function implementations for Xen.

These aren't the flask hooks.

> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/xen/xsm/xsm_core.c      Wed Aug 22 16:26:21 2007 -0400
> @@ -0,0 +1,120 @@
> +/*
> + *  This file contains the Flask hook function implementations for Xen.

neither is this

> + *  This work is based on the LSM implementation in Linux 2.6.13.4.
> + *
> + *  Author:  George Coker, <gscoker@xxxxxxxxxxxxxx>
> + *
> + *  Contributors: Michael LeMay, <mdlemay@xxxxxxxxxxxxxx>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2,
> + *  as published by the Free Software Foundation.
> + */
> +
> +#include <xen/init.h>
> +#include <xen/errno.h>
> +#include <xen/lib.h>
> +
> +#include <xsm/xsm.h>
> +
> +#ifdef XSM_ENABLE
> +
> +#define XSM_FRAMEWORK_VERSION    "1.0.0"

Could probably go, never really gets used

> +
> +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 )

Seems as if it's nearly compiled in, wonder if hook init could be made
compile time too?

> +    {
> +        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 (XEN_GUEST_HANDLE(xsm_op_t) op)
> +{
> +    return __do_xsm_op(op);
> +}
> +
> +

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.