WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: "George S. Coker, II" <gscoker@xxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [Xense-devel][RFC][PATCH][1/4] Xen Security Modules: XSM
From: Chris Wright <chrisw@xxxxxxxxxxxx>
Date: Fri, 1 Sep 2006 11:55:02 -0700
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx, xense-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Fri, 01 Sep 2006 11:55:34 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <1157129908.22006.188.camel@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1157129908.22006.188.camel@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.2.1i
* George S. Coker, II (gscoker@xxxxxxxxxxxxxx) wrote:
> The attached patch implements the Xen Security Modules (XSM) framework.
> This patch should apply cleanly to changeset 9694:d82a4c4d04d4 Xen
> 3.0.2-3.

Nice to see this all posted.  Have any perfomance numbers for default
dummy, or numbers for increase in memory footprint for this + flask +
flask example policy?  Just curious to see what the rough cost is.
Some quick comments below.

> Modules may also define at Xen compile time a magic number XSM_MAGIC to
> indicate that a policy should be discovered from the images loaded at
> boot.  The policy file should then be listed in grub as one of the
> multi-boot modules after the dom0 kernel.

I like that feature.

> 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 <asm/hvm/support.h>
>  #include <asm/processor.h>
>  #include <public/sched_ctl.h>
> +#include <xsm/xsm.h>
>  
>  #include <asm/mtrr.h>
>  #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);

Hmm, this is against 3.0.2, unfortunately you'll have some work to move
to 3.0.3 with the hypercall changes here (IIRC, this one actually
went away).  And have you done each arch?  I only see x86 here.

<snip>

> 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 <asm/shadow.h>
>  #include <asm/e820.h>
>  #include <acm/acm_hooks.h>
> +#include <xsm/xsm.h>
>  
>  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);

Seems this should drop the acm hook here, no?

>      /* 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 <public/dom0_ops.h>
>  #include <public/sched_ctl.h>
>  #include <acm/acm_hooks.h>
> +#include <xsm/xsm.h>
>  
>  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) 

shouldn't this take care of the acm_pre_dom0_op hook here as well?
IOW, at the end there shouldn't be acm specific hooks left, right?

> 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 <public/dom0_ops.h>
>  #include <public/sched.h>
>  #include <public/vcpu.h>
> +#include <xsm/xsm.h>
>  
>  /* 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/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;

What's a grant table label look like?

>      /* Mapping tracking table. */
>      grant_mapping_t      *maptrack;
>      unsigned int          maptrack_head;
> diff -r d82a4c4d04d4 -r a24b5a5f5f5b xen/include/xen/hypercall.h
> 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;
>  };

Ah, you must resue the acm domain label?  Actually would be nice to see
which objects are labelled, did I miss that list?

>  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, <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>
> +
> +#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);

Platform specific code might want ifdefs, or perhaps a just platform
specific set of ops.

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

Heh, well, that's as good as a list ;-)

> +    int (*mmu_normal_update) (struct domain *d, intpte_t fpte);
> +
> +    long (*__do_xsm_op) (GUEST_HANDLE(xsm_op_t) op);

We very intentionally did not do this in LSM (or more to the point,
we did and it was soundly rejected).  It's a free form way to extend the
hypercall interface, which in Linux is frowned upon.  Of course, you don't
have the various selinuxfs, /proc/<pid>/attr type of interfaces in the
hypervisor, but it's worth considering if there are other possibilities
(32/64-bit compat is an example of something which is easily lost when
pushing the hypercall interface down a layer into the module).

> 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 @@
> +#include <xen/sched.h>
> +#include <xsm/xsm.h>
> +
> +#ifdef XSM_ENABLE

Can you just conditionally compile in this file using the above Makefile?

> 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
<snip>
> +#ifdef XSM_ENABLE
> +#endif
> +
> +long do_xsm_op (GUEST_HANDLE(xsm_op_t) op)
> +{
> +    return __do_xsm_op(op);
> +}

Linux has the cond_syscall() macro, should be enough to do this
if you can't find a better way to do security module specifc
calls.



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