ia64/xen-unstable

changeset 15838:4ffca478e2f7

merge with xen-unstable.hg (staging)
author Alex Williamson <alex.williamson@hp.com>
date Thu Sep 06 12:05:15 2007 -0600 (2007-09-06)
parents 12be90e2f831 32f331858d75
children 8b2e0de43b55
files tools/python/xen/util/security.py xen/acm/Makefile xen/acm/acm_chinesewall_hooks.c xen/acm/acm_core.c xen/acm/acm_null_hooks.c xen/acm/acm_policy.c xen/acm/acm_simple_type_enforcement_hooks.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/mm.c xen/arch/ia64/xen/xensetup.c xen/arch/x86/cpu/mtrr/centaur.c xen/arch/x86/cpu/rise.c xen/common/acm_ops.c xen/include/acm/acm_core.h xen/include/acm/acm_endian.h xen/include/acm/acm_hooks.h xen/include/public/acm.h xen/include/public/acm_ops.h
line diff
     1.1 --- a/.hgignore	Thu Sep 06 09:05:26 2007 -0600
     1.2 +++ b/.hgignore	Thu Sep 06 12:05:15 2007 -0600
     1.3 @@ -114,6 +114,7 @@
     1.4  ^tools/firmware/vmxassist/gen$
     1.5  ^tools/firmware/vmxassist/offsets\.h$
     1.6  ^tools/firmware/vmxassist/vmxassist$
     1.7 +^tools/flask/loadpolicy/flask-loadpolicy$
     1.8  ^tools/ioemu/\.pc/.*$
     1.9  ^tools/ioemu/config-host\.h$
    1.10  ^tools/ioemu/config-host\.mak$
    1.11 @@ -149,8 +150,10 @@
    1.12  ^tools/misc/xenperf$
    1.13  ^tools/pygrub/build/.*$
    1.14  ^tools/python/build/.*$
    1.15 +^tools/python/xen/util/xsm/xsm\.py$
    1.16  ^tools/security/secpol_tool$
    1.17  ^tools/security/xen/.*$
    1.18 +^tools/security/xensec_tool$
    1.19  ^tools/tests/blowfish\.bin$
    1.20  ^tools/tests/blowfish\.h$
    1.21  ^tools/tests/test_x86_emulator$
     2.1 --- a/Config.mk	Thu Sep 06 09:05:26 2007 -0600
     2.2 +++ b/Config.mk	Thu Sep 06 12:05:15 2007 -0600
     2.3 @@ -20,6 +20,9 @@ SHELL     ?= /bin/sh
     2.4  HOSTCC      = gcc
     2.5  HOSTCFLAGS  = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
     2.6  HOSTCFLAGS += -fno-strict-aliasing
     2.7 +HOSTCFLAGS_x86_32 = -m32
     2.8 +HOSTCFLAGS_x86_64 = -m64
     2.9 +HOSTCFLAGS += $(HOSTCFLAGS_$(XEN_COMPILE_ARCH))
    2.10  
    2.11  DISTDIR     ?= $(XEN_ROOT)/dist
    2.12  DESTDIR     ?= /
    2.13 @@ -75,10 +78,10 @@ CFLAGS     += $(call cc-option,$(CC),-Wd
    2.14  LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i)) 
    2.15  CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
    2.16  
    2.17 -# If ACM_SECURITY = y, then the access control module is compiled
    2.18 -# into Xen and the policy type can be set by the boot policy file
    2.19 -#        y - Build the Xen ACM framework
    2.20 -#        n - Do not build the Xen ACM framework
    2.21 +# Enable XSM security module.  Enabling XSM requires selection of an 
    2.22 +# XSM security module (FLASK_ENABLE or ACM_SECURITY).
    2.23 +XSM_ENABLE ?= n
    2.24 +FLASK_ENABLE ?= n
    2.25  ACM_SECURITY ?= n
    2.26  
    2.27  # Optional components
     3.1 --- a/buildconfigs/mk.linux-2.6-xen	Thu Sep 06 09:05:26 2007 -0600
     3.2 +++ b/buildconfigs/mk.linux-2.6-xen	Thu Sep 06 12:05:15 2007 -0600
     3.3 @@ -7,6 +7,16 @@ EXTRAVERSION ?= -xen
     3.4  # repositories.
     3.5  LINUX_SRC_PATH ?= .:..
     3.6  
     3.7 +# The source directory is not automatically updated to avoid blowing
     3.8 +# away developer's changes. If you want to automatically pull a new
     3.9 +# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
    3.10 +# command line.
    3.11 +ifeq ($(XEN_LINUX_UPDATE),y)
    3.12 +__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
    3.13 +else
    3.14 +__XEN_LINUX_UPDATE =
    3.15 +endif
    3.16 +
    3.17  XEN_LINUX_SOURCE ?= hg-clone
    3.18  
    3.19  # Let XEN_TARGET_ARCH override ARCH.
    3.20 @@ -115,6 +125,7 @@ endif
    3.21  	      echo "	\$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT) \$$@"; \
    3.22  	    ) > $(LINUX_DIR)/Makefile ; \
    3.23  	fi
    3.24 +	$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) prepare
    3.25  
    3.26  .PHONY: prep
    3.27  prep: $(LINUX_DIR)/include/linux/autoconf.h
    3.28 @@ -137,3 +148,7 @@ delete:
    3.29  mrproper:
    3.30  	rm -rf $(LINUX_SRCDIR)
    3.31  	rm -f linux-$(LINUX_VER).tar.bz2
    3.32 +
    3.33 +.PHONY: $(LINUX_SRCDIR)/.force-update
    3.34 +$(LINUX_SRCDIR)/.force-update:
    3.35 +	@ :
     4.1 --- a/buildconfigs/src.hg-clone	Thu Sep 06 09:05:26 2007 -0600
     4.2 +++ b/buildconfigs/src.hg-clone	Thu Sep 06 12:05:15 2007 -0600
     4.3 @@ -6,16 +6,6 @@ LINUX_SRCDIR ?= linux-$(LINUX_VER)-xen.h
     4.4  # Repository to clone.
     4.5  XEN_LINUX_HGREPO ?= $$(sh buildconfigs/select-repository $(LINUX_SRCDIR) $(LINUX_SRC_PATH))
     4.6  
     4.7 -# The source directory is not automatically updated to avoid blowing
     4.8 -# away developer's changes. If you want to automatically pull a new
     4.9 -# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
    4.10 -# command line.
    4.11 -ifeq ($(XEN_LINUX_UPDATE),y)
    4.12 -__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
    4.13 -else
    4.14 -__XEN_LINUX_UPDATE =
    4.15 -endif
    4.16 -
    4.17  # Set XEN_LINUX_HGREV to update to a particlar revision.
    4.18  XEN_LINUX_HGREV  ?= tip
    4.19  
    4.20 @@ -40,7 +30,3 @@ XEN_LINUX_HGREV  ?= tip
    4.21  	    ( cd $(LINUX_SRCDIR) && $(HG) update $(XEN_LINUX_HGREV) ); \
    4.22  	fi
    4.23  	touch $@
    4.24 -
    4.25 -.PHONY: $(LINUX_SRCDIR)/.force-update
    4.26 -$(LINUX_SRCDIR)/.force-update:
    4.27 -	@ :
     5.1 --- a/buildconfigs/src.tarball	Thu Sep 06 09:05:26 2007 -0600
     5.2 +++ b/buildconfigs/src.tarball	Thu Sep 06 12:05:15 2007 -0600
     5.3 @@ -18,11 +18,11 @@ linux-%.tar.bz2:
     5.4  # XXX create a pristine tree for diff -Nurp convenience
     5.5  
     5.6  ifeq ($(XEN_LINUX_TARBALL_KETCHUP),y)
     5.7 -%/.valid-src:
     5.8 +%/.valid-src: $(__XEN_LINUX_UPDATE)
     5.9  	$(KETCHUP) -d $(@D) $(LINUX_VER)
    5.10  	touch $@ # update timestamp to avoid rebuild
    5.11  else
    5.12 -%/.valid-src: %.tar.bz2
    5.13 +%/.valid-src: $(__XEN_LINUX_UPDATE) %.tar.bz2
    5.14  	rm -rf tmp-linux-$* $(@D)
    5.15  	mkdir -p tmp-linux-$*
    5.16  	tar -C tmp-linux-$* -jxf $<
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/config/FreeBSD.mk	Thu Sep 06 12:05:15 2007 -0600
     6.3 @@ -0,0 +1,1 @@
     6.4 +include $(XEN_ROOT)/config/StdGNU.mk
     7.1 --- a/config/x86_32.mk	Thu Sep 06 09:05:26 2007 -0600
     7.2 +++ b/config/x86_32.mk	Thu Sep 06 12:05:15 2007 -0600
     7.3 @@ -11,8 +11,6 @@ CFLAGS += -m32 -march=i686
     7.4  LIBDIR := lib
     7.5  
     7.6  # Use only if calling $(LD) directly.
     7.7 -ifeq ($(XEN_OS),OpenBSD)
     7.8 -LDFLAGS_DIRECT += -melf_i386_obsd
     7.9 -else
    7.10 -LDFLAGS_DIRECT += -melf_i386
    7.11 -endif
    7.12 +LDFLAGS_DIRECT_OpenBSD = _obsd
    7.13 +LDFLAGS_DIRECT_FreeBSD = _fbsd
    7.14 +LDFLAGS_DIRECT += -melf_i386$(LDFLAGS_DIRECT_$(XEN_OS))
     8.1 --- a/docs/misc/dump-core-format.txt	Thu Sep 06 09:05:26 2007 -0600
     8.2 +++ b/docs/misc/dump-core-format.txt	Thu Sep 06 12:05:15 2007 -0600
     8.3 @@ -80,7 +80,10 @@ Currently the following sections are def
     8.4                          gmfn:   machine physical frame number
     8.5                  The size of arrays is stored in xch_nr_pages member of header
     8.6                  note descriptor in .note.Xen note section.
     8.7 -                The entryies are stored in pfn-ascending order.
     8.8 +                The entries are stored in pfn-ascending order.
     8.9 +                The value, {~(uint64_t)0, ~(uint64_t)0}, means invalid
    8.10 +                (pfn, gmfn) and the corresponding page has zero. There might
    8.11 +                exist invalid (pfn, gmfn)'s at the end part of this array.
    8.12                  This section must exist when the domain is non auto
    8.13                  translated physmap mode. Currently x86 paravirtualized domain.
    8.14  
    8.15 @@ -94,6 +97,9 @@ Currently the following sections are def
    8.16                  The size of arrays is stored in xch_nr_pages member of header
    8.17                  note descriptor in .note.Xen note section.
    8.18                  The entries are stored in ascending order.
    8.19 +                The value, ~(uint64_t)0, means invalid pfn and the
    8.20 +                corresponding page has zero. There might exist invalid
    8.21 +                pfn's at the end part of this array.
    8.22                  This section must exist when the domain is auto translated
    8.23                  physmap mode. Currently x86 full virtualized domain and
    8.24                  ia64 domain.
    8.25 @@ -225,6 +231,8 @@ Currently only (major, minor) = (0, 1) i
    8.26  
    8.27  (0, 1) update
    8.28  - .xen_p2m, .xen_pfn section
    8.29 +  Invalid pfn/gmfn.
    8.30 +- .xen_p2m, .xen_pfn section
    8.31    Arrays must be in pfn ascending order for efficient looking up.
    8.32  - EI_CLASS member of elf header was changed to ELFCLASS64 independent of
    8.33    architecture. This is mainly for x86_32pae.
     9.1 --- a/tools/Makefile	Thu Sep 06 09:05:26 2007 -0600
     9.2 +++ b/tools/Makefile	Thu Sep 06 12:05:15 2007 -0600
     9.3 @@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
     9.4  
     9.5  SUBDIRS-y :=
     9.6  SUBDIRS-y += libxc
     9.7 +SUBDIRS-y += flask
     9.8  SUBDIRS-y += xenstore
     9.9  SUBDIRS-y += misc
    9.10  SUBDIRS-y += examples
    10.1 --- a/tools/Rules.mk	Thu Sep 06 09:05:26 2007 -0600
    10.2 +++ b/tools/Rules.mk	Thu Sep 06 12:05:15 2007 -0600
    10.3 @@ -49,6 +49,8 @@ mk-symlinks:
    10.4  	( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
    10.5  	mkdir -p xen/io
    10.6  	( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
    10.7 +	mkdir -p xen/xsm
    10.8 +	( cd xen/xsm && ln -sf ../../$(XEN_ROOT)/xen/include/public/xsm/*.h . )
    10.9  	mkdir -p xen/arch-x86
   10.10  	( cd xen/arch-x86 && ln -sf ../../$(XEN_ROOT)/xen/include/public/arch-x86/*.h . )
   10.11  	mkdir -p xen/foreign
    11.1 --- a/tools/blktap/drivers/tapdisk.c	Thu Sep 06 09:05:26 2007 -0600
    11.2 +++ b/tools/blktap/drivers/tapdisk.c	Thu Sep 06 12:05:15 2007 -0600
    11.3 @@ -863,11 +863,7 @@ int main(int argc, char *argv[])
    11.4  	ptr = fd_start;
    11.5  	while (ptr != NULL) {
    11.6  		s = ptr->s;
    11.7 -
    11.8  		unmap_disk(s);
    11.9 -		free(s->blkif);
   11.10 -		free(s->ring_info);
   11.11 -		free(s);
   11.12  		close(ptr->tap_fd);
   11.13  		ptr = ptr->next;
   11.14  	}
    12.1 --- a/tools/examples/blktap	Thu Sep 06 09:05:26 2007 -0600
    12.2 +++ b/tools/examples/blktap	Thu Sep 06 12:05:15 2007 -0600
    12.3 @@ -8,6 +8,57 @@ dir=$(dirname "$0")
    12.4  
    12.5  findCommand "$@"
    12.6  
    12.7 +##
    12.8 +# check_blktap_sharing file mode
    12.9 +#
   12.10 +# Perform the sharing check for the given blktap and mode.
   12.11 +#
   12.12 +check_blktap_sharing()
   12.13 +{
   12.14 +    local file="$1"
   12.15 +    local mode="$2"
   12.16 +
   12.17 +    local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE"
   12.18 +    for dom in $(xenstore-list "$base_path")
   12.19 +    do
   12.20 +        for dev in $(xenstore-list "$base_path/$dom")
   12.21 +        do
   12.22 +            params=$(xenstore_read "$base_path/$dom/$dev/params" | cut -d: -f2)
   12.23 +            if [ "$file" = "$params" ]
   12.24 +            then
   12.25 +
   12.26 +                if [ "$mode" = 'w' ]
   12.27 +                then
   12.28 +                    if ! same_vm "$dom" 
   12.29 +                    then
   12.30 +                        echo 'guest'
   12.31 +                        return
   12.32 +                    fi
   12.33 +                else 
   12.34 +                    local m=$(xenstore_read "$base_path/$dom/$dev/mode")
   12.35 +                    m=$(canonicalise_mode "$m")
   12.36 +
   12.37 +                    if [ "$m" = 'w' ] 
   12.38 +                    then
   12.39 +                        if ! same_vm "$dom"
   12.40 +                        then
   12.41 +                            echo 'guest'
   12.42 +                            return
   12.43 +                        fi
   12.44 +                    fi
   12.45 +                fi
   12.46 +            fi
   12.47 +        done
   12.48 +    done
   12.49 +
   12.50 +    echo 'ok'
   12.51 +}
   12.52 +
   12.53 +FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
   12.54 +FRONTEND_UUID=$(xenstore_read "/local/domain/$FRONTEND_ID/vm")
   12.55 +mode=$(xenstore_read "$XENBUS_PATH/mode")
   12.56 +mode=$(canonicalise_mode "$mode")
   12.57 +
   12.58  t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
   12.59  if [ -n "$t" ]
   12.60  then
   12.61 @@ -18,7 +69,19 @@ then
   12.62          p=${p#*:}
   12.63      fi
   12.64  fi
   12.65 -file=$(readlink -f "$p") || ebusy "$p does not exist."
   12.66 +# some versions of readlink cannot be passed a regular file
   12.67 +if [ -L "$p" ]; then
   12.68 +    file=$(readlink -f "$p") || ebusy "$p link does not exist."
   12.69 +else
   12.70 +    [ -f "$p" ] || { ebusy "$p file does not exist." }
   12.71 +    file="$p"
   12.72 +fi
   12.73 +
   12.74 +if [ "$mode" != '!' ] 
   12.75 +then
   12.76 +    result=$(check_blktap_sharing "$file" "$mode")
   12.77 +    [ "$result" = 'ok' ] || ebusy "$file already in use by other domain"
   12.78 +fi
   12.79  
   12.80  if [ "$command" = 'add' ]
   12.81  then
    13.1 --- a/tools/examples/block	Thu Sep 06 09:05:26 2007 -0600
    13.2 +++ b/tools/examples/block	Thu Sep 06 12:05:15 2007 -0600
    13.3 @@ -18,32 +18,6 @@ expand_dev() {
    13.4  
    13.5  
    13.6  ##
    13.7 -# canonicalise_mode mode
    13.8 -#
    13.9 -# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
   13.10 -# thereof, and canonicalises them to one of
   13.11 -#
   13.12 -#   'r': perform checks for a new read-only mount;
   13.13 -#   'w': perform checks for a read-write mount; or
   13.14 -#   '!': perform no checks at all.
   13.15 -#
   13.16 -canonicalise_mode()
   13.17 -{
   13.18 -  local mode="$1"
   13.19 -
   13.20 -  if ! expr index "$mode" 'w' >/dev/null
   13.21 -  then
   13.22 -    echo 'r'
   13.23 -  elif ! expr index "$mode" '!' >/dev/null
   13.24 -  then
   13.25 -    echo 'w'
   13.26 -  else
   13.27 -    echo '!'
   13.28 -  fi
   13.29 -}
   13.30 -
   13.31 -
   13.32 -##
   13.33  # check_sharing device mode
   13.34  #
   13.35  # Check whether the device requested is already in use.  To use the device in
   13.36 @@ -126,22 +100,6 @@ check_sharing()
   13.37  }
   13.38  
   13.39  
   13.40 -same_vm()
   13.41 -{
   13.42 -  local otherdom="$1"
   13.43 -  # Note that othervm can be MISSING here, because Xend will be racing with
   13.44 -  # the hotplug scripts -- the entries in /local/domain can be removed by
   13.45 -  # Xend before the hotplug scripts have removed the entry in
   13.46 -  # /local/domain/0/backend/.  In this case, we want to pretend that the
   13.47 -  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
   13.48 -  # allowed.
   13.49 -  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
   13.50 -                  "$FRONTEND_UUID")
   13.51 -
   13.52 -  [ "$FRONTEND_UUID" = "$othervm" ]
   13.53 -}
   13.54 -
   13.55 -
   13.56  ##
   13.57  # check_device_sharing dev mode
   13.58  #
    14.1 --- a/tools/examples/block-common.sh	Thu Sep 06 09:05:26 2007 -0600
    14.2 +++ b/tools/examples/block-common.sh	Thu Sep 06 12:05:15 2007 -0600
    14.3 @@ -71,3 +71,46 @@ write_dev() {
    14.4  
    14.5    success
    14.6  }
    14.7 +
    14.8 +
    14.9 +##
   14.10 +# canonicalise_mode mode
   14.11 +#
   14.12 +# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
   14.13 +# thereof, and canonicalises them to one of
   14.14 +#
   14.15 +#   'r': perform checks for a new read-only mount;
   14.16 +#   'w': perform checks for a read-write mount; or
   14.17 +#   '!': perform no checks at all.
   14.18 +#
   14.19 +canonicalise_mode()
   14.20 +{
   14.21 +  local mode="$1"
   14.22 +
   14.23 +  if ! expr index "$mode" 'w' >/dev/null
   14.24 +  then
   14.25 +    echo 'r'
   14.26 +  elif ! expr index "$mode" '!' >/dev/null
   14.27 +  then
   14.28 +    echo 'w'
   14.29 +  else
   14.30 +    echo '!'
   14.31 +  fi
   14.32 +}
   14.33 +
   14.34 +
   14.35 +same_vm()
   14.36 +{
   14.37 +  local otherdom="$1"
   14.38 +  # Note that othervm can be MISSING here, because Xend will be racing with
   14.39 +  # the hotplug scripts -- the entries in /local/domain can be removed by
   14.40 +  # Xend before the hotplug scripts have removed the entry in
   14.41 +  # /local/domain/0/backend/.  In this case, we want to pretend that the
   14.42 +  # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
   14.43 +  # allowed.
   14.44 +  local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
   14.45 +                  "$FRONTEND_UUID")
   14.46 +
   14.47 +  [ "$FRONTEND_UUID" = "$othervm" ]
   14.48 +}
   14.49 +
    15.1 --- a/tools/examples/network-bridge	Thu Sep 06 09:05:26 2007 -0600
    15.2 +++ b/tools/examples/network-bridge	Thu Sep 06 12:05:15 2007 -0600
    15.3 @@ -259,7 +259,8 @@ add_to_bridge2() {
    15.4  	fi
    15.5      done
    15.6  
    15.7 -    if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi
    15.8 +    if [ ${i} -eq ${maxtries} ] ; then echo -n '(link isnt in running state)' ; fi
    15.9 +    echo
   15.10  
   15.11      add_to_bridge ${bridge} ${dev}
   15.12  }
    16.1 --- a/tools/firmware/hvmloader/smbios.c	Thu Sep 06 09:05:26 2007 -0600
    16.2 +++ b/tools/firmware/hvmloader/smbios.c	Thu Sep 06 12:05:15 2007 -0600
    16.3 @@ -159,8 +159,7 @@ get_memsize(void)
    16.4  int
    16.5  hvm_write_smbios_tables(void)
    16.6  {
    16.7 -    uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
    16.8 -                         not uint8_t[16]. ** */
    16.9 +    xen_domain_handle_t uuid;
   16.10      uint16_t xen_major_version, xen_minor_version;
   16.11      uint32_t xen_version;
   16.12      char xen_extra_version[XEN_EXTRAVERSION_LEN];
   16.13 @@ -173,6 +172,7 @@ hvm_write_smbios_tables(void)
   16.14      unsigned tmp_len; /* length of next string to add */
   16.15  
   16.16      hypercall_xen_version(XENVER_guest_handle, uuid);
   16.17 +    BUILD_BUG_ON(sizeof(xen_domain_handle_t) != 16);
   16.18  
   16.19      /* xen_version major and minor */
   16.20      xen_version = hypercall_xen_version(XENVER_version, NULL);
    17.1 --- a/tools/firmware/hvmloader/util.h	Thu Sep 06 09:05:26 2007 -0600
    17.2 +++ b/tools/firmware/hvmloader/util.h	Thu Sep 06 12:05:15 2007 -0600
    17.3 @@ -17,6 +17,7 @@ extern void __assert_failed(char *assert
    17.4  extern void __bug(char *file, int line) __attribute__((noreturn));
    17.5  #define BUG() __bug(__FILE__, __LINE__)
    17.6  #define BUG_ON(p) do { if (p) BUG(); } while (0)
    17.7 +#define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
    17.8  
    17.9  /* I/O output */
   17.10  void outb(uint16_t addr, uint8_t  val);
    18.1 --- a/tools/firmware/rombios/rombios.c	Thu Sep 06 09:05:26 2007 -0600
    18.2 +++ b/tools/firmware/rombios/rombios.c	Thu Sep 06 12:05:15 2007 -0600
    18.3 @@ -1057,7 +1057,7 @@ static char CVSID[] = "$Id: rombios.c,v 
    18.4  #define UNSUPPORTED_FUNCTION 0x86
    18.5  
    18.6  #define none 0
    18.7 -#define MAX_SCAN_CODE 0x53
    18.8 +#define MAX_SCAN_CODE 0x58
    18.9  
   18.10  static struct {
   18.11    Bit16u normal;
   18.12 @@ -1149,7 +1149,12 @@ static struct {
   18.13        { 0x5000, 0x5032,   none,   none, 0x20 }, /* 2 Down */
   18.14        { 0x5100, 0x5133, 0x7600,   none, 0x20 }, /* 3 PgDn */
   18.15        { 0x5200, 0x5230,   none,   none, 0x20 }, /* 0 Ins */
   18.16 -      { 0x5300, 0x532e,   none,   none, 0x20 }  /* Del */
   18.17 +      { 0x5300, 0x532e,   none,   none, 0x20 }, /* Del */
   18.18 +      {   none,   none,   none,   none, none }, /* ??? */
   18.19 +      {   none,   none,   none,   none, none }, /* ??? */
   18.20 +      {   none,   none,   none,   none, none }, /* ??? */
   18.21 +      { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */
   18.22 +      { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */
   18.23        };
   18.24  
   18.25    Bit8u
   18.26 @@ -4682,7 +4687,7 @@ int09_function(DI, SI, BP, SP, BX, DX, C
   18.27      default:
   18.28        if (scancode & 0x80) return; /* toss key releases ... */
   18.29        if (scancode > MAX_SCAN_CODE) {
   18.30 -        BX_INFO("KBD: int09h_handler(): unknown scancode read!\n");
   18.31 +        BX_INFO("KBD: int09h_handler(): unknown scancode (%x) read!\n", scancode);
   18.32          return;
   18.33          }
   18.34        if (shift_flags & 0x08) { /* ALT */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/flask/Makefile	Thu Sep 06 12:05:15 2007 -0600
    19.3 @@ -0,0 +1,26 @@
    19.4 +XEN_ROOT = ../..
    19.5 +include $(XEN_ROOT)/tools/Rules.mk
    19.6 +
    19.7 +SUBDIRS :=
    19.8 +SUBDIRS += libflask
    19.9 +SUBDIRS += loadpolicy
   19.10 +
   19.11 +.PHONY: all
   19.12 +all:
   19.13 +	@set -e; for subdir in $(SUBDIRS); do \
   19.14 +		$(MAKE) -C $$subdir $@; \
   19.15 +	done
   19.16 +
   19.17 +.PHONY: install
   19.18 +install:
   19.19 +	@set -e; for subdir in $(SUBDIRS); do \
   19.20 +		$(MAKE) -C $$subdir $@; \
   19.21 +	done
   19.22 +
   19.23 +.PHONY: clean
   19.24 +clean:
   19.25 +	@set -e; for subdir in $(SUBDIRS); do \
   19.26 +		$(MAKE) -C $$subdir $@; \
   19.27 +	done
   19.28 +
   19.29 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/flask/libflask/Makefile	Thu Sep 06 12:05:15 2007 -0600
    20.3 @@ -0,0 +1,65 @@
    20.4 +MAJOR    = 1.0
    20.5 +MINOR    = 0
    20.6 +
    20.7 +XEN_ROOT = ../../..
    20.8 +include $(XEN_ROOT)/tools/Rules.mk
    20.9 +
   20.10 +XEN_LIBXC = $(XEN_ROOT)/tools/libxc
   20.11 +
   20.12 +SRCS       :=
   20.13 +SRCS       += flask_op.c
   20.14 +
   20.15 +CFLAGS   += -Werror
   20.16 +CFLAGS   += -fno-strict-aliasing
   20.17 +CFLAGS   += $(INCLUDES) -I./include -I$(XEN_LIBXC) 
   20.18 +
   20.19 +# Get gcc to generate the dependencies for us.
   20.20 +CFLAGS   += -Wp,-MD,.$(@F).d
   20.21 +LDFLAGS  += -L.
   20.22 +DEPS     = .*.d
   20.23 +
   20.24 +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
   20.25 +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
   20.26 +
   20.27 +LIB := libflask.a
   20.28 +LIB += libflask.so libflask.so.$(MAJOR) libflask.so.$(MAJOR).$(MINOR)
   20.29 +
   20.30 +.PHONY: all
   20.31 +all: build
   20.32 +
   20.33 +.PHONY: build
   20.34 +build:
   20.35 +	$(MAKE) $(LIB)
   20.36 +
   20.37 +.PHONY: install
   20.38 +install: build
   20.39 +	[ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)
   20.40 +	[ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include
   20.41 +	$(INSTALL_PROG) libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
   20.42 +	$(INSTALL_DATA) libflask.a $(DESTDIR)/usr/$(LIBDIR)
   20.43 +	ln -sf libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so.$(MAJOR)
   20.44 +	ln -sf libflask.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so
   20.45 +	$(INSTALL_DATA) include/flask_op.h $(DESTDIR)/usr/include
   20.46 +
   20.47 +.PHONY: TAGS
   20.48 +TAGS:
   20.49 +	etags -t *.c *.h
   20.50 +
   20.51 +.PHONY: clean
   20.52 +clean:
   20.53 +	rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen
   20.54 +
   20.55 +# libflask
   20.56 +
   20.57 +libflask.a: $(LIB_OBJS)
   20.58 +	$(AR) rc $@ $^
   20.59 +
   20.60 +libflask.so: libflask.so.$(MAJOR)
   20.61 +	ln -sf $< $@
   20.62 +libflask.so.$(MAJOR): libflask.so.$(MAJOR).$(MINOR)
   20.63 +	ln -sf $< $@
   20.64 +
   20.65 +libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
   20.66 +	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libflask.so.$(MAJOR) -shared -o $@ $^
   20.67 +
   20.68 +-include $(DEPS)
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/flask/libflask/flask_op.c	Thu Sep 06 12:05:15 2007 -0600
    21.3 @@ -0,0 +1,100 @@
    21.4 +/*
    21.5 + *
    21.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
    21.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
    21.8 + *
    21.9 + *  This program is free software; you can redistribute it and/or modify
   21.10 + *  it under the terms of the GNU General Public License version 2,
   21.11 + *  as published by the Free Software Foundation.
   21.12 + */
   21.13 +
   21.14 +#include <unistd.h>
   21.15 +#include <stdio.h>
   21.16 +#include <errno.h>
   21.17 +#include <fcntl.h>
   21.18 +#include <string.h>
   21.19 +#include <sys/mman.h>
   21.20 +#include <sys/types.h>
   21.21 +#include <sys/stat.h>
   21.22 +#include <stdlib.h>
   21.23 +#include <sys/ioctl.h>
   21.24 +
   21.25 +#include <xc_private.h>
   21.26 +
   21.27 +#include <flask_op.h>
   21.28 +
   21.29 +int flask_load(int xc_handle, char *buf, int size)
   21.30 +{
   21.31 +    int err;
   21.32 +    flask_op_t op;
   21.33 +    
   21.34 +    op.cmd = FLASK_LOAD;
   21.35 +    op.buf = buf;
   21.36 +    op.size = size;
   21.37 +    
   21.38 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
   21.39 +        return err;
   21.40 +
   21.41 +    return 0;
   21.42 +}
   21.43 +
   21.44 +int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid)
   21.45 +{
   21.46 +    int err;
   21.47 +    flask_op_t op;
   21.48 +    
   21.49 +    op.cmd = FLASK_CONTEXT_TO_SID;
   21.50 +    op.buf = buf;
   21.51 +    op.size = size;
   21.52 +    
   21.53 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
   21.54 +        return err;
   21.55 +    
   21.56 +    sscanf(buf, "%u", sid);
   21.57 +
   21.58 +    return 0;
   21.59 +}
   21.60 +
   21.61 +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size)
   21.62 +{
   21.63 +    int err;
   21.64 +    flask_op_t op;
   21.65 +    
   21.66 +    op.cmd = FLASK_SID_TO_CONTEXT;
   21.67 +    op.buf = buf;
   21.68 +    op.size = size;
   21.69 +    
   21.70 +    snprintf(buf, size, "%u", sid);
   21.71 +
   21.72 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
   21.73 +        return err;
   21.74 +
   21.75 +    return 0;
   21.76 +}
   21.77 +
   21.78 +int do_flask_op(int xc_handle, flask_op_t *op)
   21.79 +{
   21.80 +    int ret = -1;
   21.81 +    DECLARE_HYPERCALL;
   21.82 +
   21.83 +    hypercall.op     = __HYPERVISOR_xsm_op;
   21.84 +    hypercall.arg[0] = (unsigned long)op;
   21.85 +
   21.86 +    if ( mlock(op, sizeof(*op)) != 0 )
   21.87 +    {
   21.88 +        PERROR("Could not lock memory for Xen hypercall");
   21.89 +        goto out;
   21.90 +    }
   21.91 +
   21.92 +    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
   21.93 +    {
   21.94 +        if ( errno == EACCES )
   21.95 +            fprintf(stderr, "XSM operation failed!\n");
   21.96 +    }
   21.97 +
   21.98 +    safe_munlock(op, sizeof(*op));
   21.99 +
  21.100 + out:
  21.101 +    return ret;
  21.102 +}
  21.103 +
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/flask/libflask/include/flask_op.h	Thu Sep 06 12:05:15 2007 -0600
    22.3 @@ -0,0 +1,46 @@
    22.4 +/*
    22.5 + *
    22.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
    22.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
    22.8 + *
    22.9 + *  This program is free software; you can redistribute it and/or modify
   22.10 + *  it under the terms of the GNU General Public License version 2,
   22.11 + *  as published by the Free Software Foundation.
   22.12 + */
   22.13 +
   22.14 +#ifndef __FLASK_OP_H
   22.15 +#define __FLASK_OP_H
   22.16 +
   22.17 +#define FLASK_LOAD              1
   22.18 +#define FLASK_GETENFORCE        2
   22.19 +#define FLASK_SETENFORCE        3
   22.20 +#define FLASK_CONTEXT_TO_SID    4
   22.21 +#define FLASK_SID_TO_CONTEXT    5
   22.22 +#define FLASK_ACCESS            6
   22.23 +#define FLASK_CREATE            7
   22.24 +#define FLASK_RELABEL           8
   22.25 +#define FLASK_USER              9
   22.26 +#define FLASK_POLICYVERS        10
   22.27 +#define FLASK_GETBOOL           11
   22.28 +#define FLASK_SETBOOL           12
   22.29 +#define FLASK_COMMITBOOLS       13
   22.30 +#define FLASK_MLS               14
   22.31 +#define FLASK_DISABLE           15
   22.32 +#define FLASK_GETAVC_THRESHOLD  16
   22.33 +#define FLASK_SETAVC_THRESHOLD  17
   22.34 +#define FLASK_AVC_HASHSTATS     18
   22.35 +#define FLASK_AVC_CACHESTATS    19
   22.36 +#define FLASK_MEMBER            20
   22.37 +
   22.38 +typedef struct flask_op {
   22.39 +    int   cmd;
   22.40 +    int   size;
   22.41 +    char *buf;
   22.42 +} flask_op_t;
   22.43 +
   22.44 +int flask_load(int xc_handle, char *buf, int size);
   22.45 +int flask_context_to_sid(int xc_handle, char *buf, int size, u_int32_t *sid);
   22.46 +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size);
   22.47 +int do_flask_op(int xc_handle, flask_op_t *op);
   22.48 +
   22.49 +#endif
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/flask/loadpolicy/Makefile	Thu Sep 06 12:05:15 2007 -0600
    23.3 @@ -0,0 +1,61 @@
    23.4 +XEN_ROOT=../../..
    23.5 +include $(XEN_ROOT)/tools/Rules.mk
    23.6 +XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
    23.7 +
    23.8 +INSTALL         = install
    23.9 +INSTALL_DATA    = $(INSTALL) -m0644
   23.10 +INSTALL_PROG    = $(INSTALL) -m0755
   23.11 +INSTALL_DIR     = $(INSTALL) -d -m0755
   23.12 +
   23.13 +LIBXC_ROOT = $(XEN_ROOT)/tools/libxc
   23.14 +LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask
   23.15 +
   23.16 +PROFILE=#-pg
   23.17 +BASECFLAGS=-Wall -g -Werror
   23.18 +# Make gcc generate dependencies.
   23.19 +BASECFLAGS += -Wp,-MD,.$(@F).d
   23.20 +PROG_DEP = .*.d
   23.21 +BASECFLAGS+= $(PROFILE)
   23.22 +#BASECFLAGS+= -I$(XEN_ROOT)/tools
   23.23 +BASECFLAGS+= -I$(LIBXC_ROOT)
   23.24 +BASECFLAGS+= -I$(LIBFLASK_ROOT)/include
   23.25 +BASECFLAGS+= -I.
   23.26 +
   23.27 +CFLAGS  += $(BASECFLAGS)
   23.28 +LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT)
   23.29 +TESTDIR  = testsuite/tmp
   23.30 +TESTFLAGS= -DTESTING
   23.31 +TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
   23.32 +
   23.33 +CLIENTS := flask-loadpolicy
   23.34 +CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS))
   23.35 +
   23.36 +.PHONY: all
   23.37 +all: $(CLIENTS)
   23.38 +
   23.39 +$(CLIENTS): flask-%: %.o
   23.40 +	$(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lflask -lxenctrl -o $@
   23.41 +
   23.42 +.PHONY: clean
   23.43 +clean: 
   23.44 +	rm -f *.o *.opic *.so
   23.45 +	rm -f $(CLIENTS)
   23.46 +	$(RM) $(PROG_DEP)
   23.47 +
   23.48 +.PHONY: print-dir
   23.49 +print-dir:
   23.50 +	@echo -n tools/flask/loadpolicy: 
   23.51 +
   23.52 +.PHONY: print-end
   23.53 +print-end:
   23.54 +	@echo
   23.55 +
   23.56 +.PHONY: install
   23.57 +install: all
   23.58 +	$(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
   23.59 +	$(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/sbin
   23.60 +
   23.61 +-include $(PROG_DEP)
   23.62 +
   23.63 +# never delete any intermediate files.
   23.64 +.SECONDARY:
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/flask/loadpolicy/loadpolicy.c	Thu Sep 06 12:05:15 2007 -0600
    24.3 @@ -0,0 +1,130 @@
    24.4 +/*
    24.5 + *
    24.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
    24.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
    24.8 + *
    24.9 + *    This program is free software; you can redistribute it and/or modify
   24.10 + *    it under the terms of the GNU General Public License version 2,
   24.11 + *      as published by the Free Software Foundation.
   24.12 + */
   24.13 +
   24.14 +#include <stdlib.h>
   24.15 +#include <errno.h>
   24.16 +#include <stdio.h>
   24.17 +#include <xenctrl.h>
   24.18 +#include <fcntl.h>
   24.19 +#include <sys/mman.h>
   24.20 +#include <sys/stat.h>
   24.21 +#include <string.h>
   24.22 +#include <unistd.h>
   24.23 +
   24.24 +#include <flask_op.h>
   24.25 +
   24.26 +#define USE_MMAP
   24.27 +
   24.28 +static void usage (int argCnt, const char *args[])
   24.29 +{
   24.30 +    fprintf(stderr, "Usage: %s <policy.file>\n", args[0]);
   24.31 +    exit(1);
   24.32 +}
   24.33 +
   24.34 +int main (int argCnt, const char *args[])
   24.35 +{
   24.36 +    const char *polFName;
   24.37 +    int polFd = 0;
   24.38 +    void *polMem = NULL;
   24.39 +    void *polMemCp = NULL;
   24.40 +    struct stat info;
   24.41 +    int ret;
   24.42 +    int xch = 0;
   24.43 +
   24.44 +    if (argCnt != 2)
   24.45 +        usage(argCnt, args);
   24.46 +
   24.47 +    polFName = args[1];
   24.48 +    polFd = open(polFName, O_RDONLY);
   24.49 +    if ( polFd < 0 )
   24.50 +    {
   24.51 +        fprintf(stderr, "Error occurred opening policy file '%s': %s\n",
   24.52 +                polFName, strerror(errno));
   24.53 +        ret = -1;
   24.54 +        goto cleanup;
   24.55 +    }
   24.56 +    
   24.57 +    ret = stat(polFName, &info);
   24.58 +    if ( ret < 0 )
   24.59 +    {
   24.60 +        fprintf(stderr, "Error occurred retrieving information about"
   24.61 +                "policy file '%s': %s\n", polFName, strerror(errno));
   24.62 +        goto cleanup;
   24.63 +    }
   24.64 +
   24.65 +    polMemCp = malloc(info.st_size);
   24.66 +
   24.67 +#ifdef USE_MMAP
   24.68 +    polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0);
   24.69 +    if ( !polMem )
   24.70 +    {
   24.71 +        fprintf(stderr, "Error occurred mapping policy file in memory: %s\n",
   24.72 +                strerror(errno));
   24.73 +        ret = -1;
   24.74 +        goto cleanup;
   24.75 +    }
   24.76 +
   24.77 +    xch = xc_interface_open();
   24.78 +    if ( xch < 0 )
   24.79 +    {
   24.80 +        fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
   24.81 +                strerror(errno));
   24.82 +        ret = -1;
   24.83 +        goto cleanup;
   24.84 +    }
   24.85 +
   24.86 +    memcpy(polMemCp, polMem, info.st_size);
   24.87 +#else
   24.88 +    ret = read(polFd, polMemCp, info.st_size);
   24.89 +    if ( ret < 0 )
   24.90 +    {
   24.91 +        fprintf(stderr, "Unable to read new Flask policy file: %s\n",
   24.92 +                strerror(errno));
   24.93 +        goto cleanup;
   24.94 +    }
   24.95 +    else
   24.96 +    {
   24.97 +        printf("Read %d bytes from policy file '%s'.\n", ret, polFName);
   24.98 +    }
   24.99 +#endif
  24.100 +
  24.101 +    ret = flask_load(xch, polMemCp, info.st_size);
  24.102 +    if ( ret < 0 )
  24.103 +    {
  24.104 +        errno = -ret;
  24.105 +        fprintf(stderr, "Unable to load new Flask policy: %s\n",
  24.106 +                strerror(errno));
  24.107 +        ret = -1;
  24.108 +        goto cleanup;
  24.109 +    }
  24.110 +    else
  24.111 +    {
  24.112 +        printf("Successfully loaded policy.\n");
  24.113 +    }
  24.114 +
  24.115 +done:
  24.116 +    if ( polMemCp )
  24.117 +        free(polMemCp);
  24.118 +    if ( polMem )
  24.119 +    {
  24.120 +        ret = munmap(polMem, info.st_size);
  24.121 +        if ( ret < 0 )
  24.122 +            fprintf(stderr, "Unable to unmap policy memory: %s\n", strerror(errno));
  24.123 +    }
  24.124 +    if ( polFd )
  24.125 +        close(polFd);
  24.126 +    if ( xch )
  24.127 +        xc_interface_close(xch);
  24.128 +
  24.129 +    return ret;
  24.130 +
  24.131 +cleanup:
  24.132 +    goto done;
  24.133 +}
    25.1 --- a/tools/ioemu/Makefile.target	Thu Sep 06 09:05:26 2007 -0600
    25.2 +++ b/tools/ioemu/Makefile.target	Thu Sep 06 12:05:15 2007 -0600
    25.3 @@ -197,7 +197,6 @@ CPPFLAGS+=-D_GNU_SOURCE
    25.4  LIBS+=-lm
    25.5  LIBS+=-L../../libxc -lxenctrl -lxenguest
    25.6  LIBS+=-L../../xenstore -lxenstore
    25.7 -LIBS+=-lpthread
    25.8  ifndef CONFIG_USER_ONLY
    25.9  LIBS+=-lz
   25.10  endif
    26.1 --- a/tools/ioemu/hw/cirrus_vga.c	Thu Sep 06 09:05:26 2007 -0600
    26.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Thu Sep 06 12:05:15 2007 -0600
    26.3 @@ -2559,7 +2559,11 @@ static void *set_vram_mapping(unsigned l
    26.4      for (i = 0; i < nr_extents; i++)
    26.5          extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
    26.6  
    26.7 -    set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
    26.8 +    if (set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start) < 0) {
    26.9 +        fprintf(logfile, "Failed set_mm_mapping\n");
   26.10 +        free(extent_start);
   26.11 +        return NULL;
   26.12 +    }
   26.13  
   26.14      vram_pointer = xc_map_foreign_batch(xc_handle, domid,
   26.15                                          PROT_READ|PROT_WRITE,
   26.16 @@ -2567,6 +2571,7 @@ static void *set_vram_mapping(unsigned l
   26.17      if (vram_pointer == NULL) {
   26.18          fprintf(logfile, "xc_map_foreign_batch vgaram returned error %d\n",
   26.19                  errno);
   26.20 +        free(extent_start);
   26.21          return NULL;
   26.22      }
   26.23  
    27.1 --- a/tools/ioemu/hw/ide.c	Thu Sep 06 09:05:26 2007 -0600
    27.2 +++ b/tools/ioemu/hw/ide.c	Thu Sep 06 12:05:15 2007 -0600
    27.3 @@ -1876,6 +1876,9 @@ static void ide_ioport_write(void *opaqu
    27.4                  break;
    27.5              case 0xaa: /* read look-ahead enable */
    27.6              case 0x55: /* read look-ahead disable */
    27.7 +            case 0x42: /* EN_AAM: enable Automatic Acoustic Mode */
    27.8 +            case 0xc2: /* DIS_AAM: disable Automatic Acoustic Mode */
    27.9 +            case 0x85: /* DIS_APM: disable APM */
   27.10                  s->status = READY_STAT | SEEK_STAT;
   27.11                  ide_set_irq(s);
   27.12                  break;
   27.13 @@ -1914,8 +1917,15 @@ static void ide_ioport_write(void *opaqu
   27.14  	    s->status = READY_STAT;
   27.15              ide_set_irq(s);
   27.16              break;
   27.17 -	case WIN_STANDBYNOW1:
   27.18          case WIN_IDLEIMMEDIATE:
   27.19 +        case WIN_STANDBY:
   27.20 +        case WIN_SETIDLE1:
   27.21 +        case WIN_STANDBYNOW1:
   27.22 +        case WIN_SLEEPNOW1:
   27.23 +        case WIN_STANDBY2:
   27.24 +        case WIN_SETIDLE2:
   27.25 +        case WIN_STANDBYNOW2:
   27.26 +        case WIN_SLEEPNOW2:
   27.27  	    s->status = READY_STAT;
   27.28              ide_set_irq(s);
   27.29              break;
    28.1 --- a/tools/ioemu/hw/tpm_tis.c	Thu Sep 06 09:05:26 2007 -0600
    28.2 +++ b/tools/ioemu/hw/tpm_tis.c	Thu Sep 06 12:05:15 2007 -0600
    28.3 @@ -154,16 +154,16 @@ static int has_channel_local_socket(tpmS
    28.4  #define NUM_TRANSPORTS 1
    28.5  
    28.6  struct vTPM_transmit {
    28.7 -    int (*open) (tpmState *s, uint32_t vtpm_instance);
    28.8 -    int (*write) (tpmState *s, const tpmBuffer *);
    28.9 -    int (*read) (tpmState *s, tpmBuffer *);
   28.10 -    int (*close) (tpmState *s, int);
   28.11 +    int (*open_fn) (tpmState *s, uint32_t vtpm_instance);
   28.12 +    int (*write_fn) (tpmState *s, const tpmBuffer *);
   28.13 +    int (*read_fn) (tpmState *s, tpmBuffer *);
   28.14 +    int (*close_fn) (tpmState *s, int);
   28.15      int (*has_channel) (tpmState *s);
   28.16  } vTPMTransmit[NUM_TRANSPORTS] = {
   28.17 -    { .open = create_local_socket,
   28.18 -      .write = write_local_socket,
   28.19 -      .read = read_local_socket,
   28.20 -      .close = close_local_socket,
   28.21 +    { .open_fn = create_local_socket,
   28.22 +      .write_fn = write_local_socket,
   28.23 +      .read_fn = read_local_socket,
   28.24 +      .close_fn = close_local_socket,
   28.25        .has_channel = has_channel_local_socket,
   28.26      }
   28.27  };
   28.28 @@ -200,7 +200,7 @@ static void open_vtpm_channel(tpmState *
   28.29      int idx;
   28.30      /* search a usable transmit layer */
   28.31      for (idx = 0; idx < NUM_TRANSPORTS; idx++) {
   28.32 -        if (1 == vTPMTransmit[idx].open(s, s->vtpm_instance)) {
   28.33 +        if (1 == vTPMTransmit[idx].open_fn(s, s->vtpm_instance)) {
   28.34              /* found one */
   28.35              s->Transmitlayer = idx;
   28.36              break;
   28.37 @@ -213,7 +213,7 @@ static void open_vtpm_channel(tpmState *
   28.38   */
   28.39  static inline void close_vtpm_channel(tpmState *s, int force)
   28.40  {
   28.41 -    if (1 == vTPMTransmit[s->Transmitlayer].close(s, force)) {
   28.42 +    if (1 == vTPMTransmit[s->Transmitlayer].close_fn(s, force)) {
   28.43          s->Transmitlayer = -1;
   28.44      }
   28.45  }
   28.46 @@ -974,7 +974,7 @@ static int TPM_Send(tpmState *s, tpmBuff
   28.47      buffer->instance[0] &= 0x1f;
   28.48      buffer->instance[0] |= (locty << 5);
   28.49  
   28.50 -    len = vTPMTransmit[s->Transmitlayer].write(s, buffer);
   28.51 +    len = vTPMTransmit[s->Transmitlayer].write_fn(s, buffer);
   28.52      if (len < 0) {
   28.53          s->Transmitlayer = -1;
   28.54      }
   28.55 @@ -990,7 +990,7 @@ static int TPM_Receive(tpmState *s, tpmB
   28.56  {
   28.57      int off;
   28.58  
   28.59 -    off = vTPMTransmit[s->Transmitlayer].read(s, buffer);
   28.60 +    off = vTPMTransmit[s->Transmitlayer].read_fn(s, buffer);
   28.61  
   28.62      if (off < 0) {
   28.63          /* EAGAIN is set in errno due to non-blocking mode */
    29.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Thu Sep 06 09:05:26 2007 -0600
    29.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Thu Sep 06 12:05:15 2007 -0600
    29.3 @@ -125,17 +125,10 @@ static int io_mem_nb = 1;
    29.4  FILE *logfile;
    29.5  int loglevel;
    29.6  
    29.7 -#ifdef MAPCACHE
    29.8 -pthread_mutex_t mapcache_mutex;
    29.9 -#endif
   29.10 -
   29.11  void cpu_exec_init(CPUState *env)
   29.12  {
   29.13      CPUState **penv;
   29.14      int cpu_index;
   29.15 -#ifdef MAPCACHE
   29.16 -    pthread_mutexattr_t mxattr; 
   29.17 -#endif
   29.18  
   29.19      env->next_cpu = NULL;
   29.20      penv = &first_cpu;
   29.21 @@ -149,14 +142,6 @@ void cpu_exec_init(CPUState *env)
   29.22  
   29.23      /* alloc dirty bits array */
   29.24      phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
   29.25 -
   29.26 -#ifdef MAPCACHE
   29.27 -    /* setup memory access mutex to protect mapcache */
   29.28 -    pthread_mutexattr_init(&mxattr); 
   29.29 -    pthread_mutexattr_settype(&mxattr, PTHREAD_MUTEX_RECURSIVE);
   29.30 -    pthread_mutex_init(&mapcache_mutex, &mxattr); 
   29.31 -    pthread_mutexattr_destroy(&mxattr); 
   29.32 -#endif
   29.33  }
   29.34  
   29.35  /* enable or disable low levels log */
   29.36 @@ -470,6 +455,12 @@ static void memcpy_words(void *dst, void
   29.37  #else
   29.38  static void memcpy_words(void *dst, void *src, size_t n)
   29.39  {
   29.40 +    /* Some architectures do not like unaligned accesses. */
   29.41 +    if (((unsigned long)dst | (unsigned long)src) & 3) {
   29.42 +        memcpy(dst, src, n);
   29.43 +        return;
   29.44 +    }
   29.45 +
   29.46      while (n >= sizeof(uint32_t)) {
   29.47          *((uint32_t *)dst) = *((uint32_t *)src);
   29.48          dst = ((uint32_t *)dst) + 1;
    30.1 --- a/tools/ioemu/vl.h	Thu Sep 06 09:05:26 2007 -0600
    30.2 +++ b/tools/ioemu/vl.h	Thu Sep 06 12:05:15 2007 -0600
    30.3 @@ -160,26 +160,16 @@ extern FILE *logfile;
    30.4  
    30.5  
    30.6  #if defined(__i386__) || defined(__x86_64__)
    30.7 -
    30.8  #define MAPCACHE
    30.9 -
   30.10  uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
   30.11  void     qemu_invalidate_map_cache(void);
   30.12 -
   30.13 -#include <pthread.h>
   30.14 -extern  pthread_mutex_t mapcache_mutex;
   30.15 -#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
   30.16 -#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
   30.17 -
   30.18  #else 
   30.19 -
   30.20  #define qemu_invalidate_map_cache() ((void)0)
   30.21 +#endif
   30.22  
   30.23  #define mapcache_lock()   ((void)0)
   30.24  #define mapcache_unlock() ((void)0)
   30.25  
   30.26 -#endif
   30.27 -
   30.28  extern int xc_handle;
   30.29  extern int domid;
   30.30  
    31.1 --- a/tools/libxc/xc_acm.c	Thu Sep 06 09:05:26 2007 -0600
    31.2 +++ b/tools/libxc/xc_acm.c	Thu Sep 06 12:05:15 2007 -0600
    31.3 @@ -81,7 +81,7 @@ int xc_acm_op(int xc_handle, int cmd, vo
    31.4      acmctl.cmd = cmd;
    31.5      acmctl.interface_version = ACM_INTERFACE_VERSION;
    31.6  
    31.7 -    hypercall.op = __HYPERVISOR_acm_op;
    31.8 +    hypercall.op = __HYPERVISOR_xsm_op;
    31.9      hypercall.arg[0] = (unsigned long)&acmctl;
   31.10      if ( lock_pages(&acmctl, sizeof(acmctl)) != 0)
   31.11      {
    32.1 --- a/tools/libxc/xc_core.c	Thu Sep 06 09:05:26 2007 -0600
    32.2 +++ b/tools/libxc/xc_core.c	Thu Sep 06 12:05:15 2007 -0600
    32.3 @@ -17,8 +17,8 @@
    32.4   *  |    .xen_prstatus                                       |
    32.5   *  |    .xen_ia64_mmapped_regs if ia64                      |
    32.6   *  |    .xen_shared_info if present                         |
    32.7 + *  |    .xen_pages                                          |
    32.8   *  |    .xen_p2m or .xen_pfn                                |
    32.9 - *  |    .xen_pages                                          |
   32.10   *  +--------------------------------------------------------+
   32.11   *  |.note.Xen:note section                                  |
   32.12   *  |    "Xen" is used as note name,                         |
   32.13 @@ -37,13 +37,13 @@
   32.14   *  +--------------------------------------------------------+
   32.15   *  |.xen_shared_info if possible                            |
   32.16   *  +--------------------------------------------------------+
   32.17 + *  |.xen_pages                                              |
   32.18 + *  |    page * nr_pages                                     |
   32.19 + *  +--------------------------------------------------------+
   32.20   *  |.xen_p2m or .xen_pfn                                    |
   32.21   *  |    .xen_p2m: struct xen_dumpcore_p2m[nr_pages]         |
   32.22   *  |    .xen_pfn: uint64_t[nr_pages]                        |
   32.23   *  +--------------------------------------------------------+
   32.24 - *  |.xen_pages                                              |
   32.25 - *  |    page * nr_pages                                     |
   32.26 - *  +--------------------------------------------------------+
   32.27   *  |.shstrtab: section header string table                  |
   32.28   *  +--------------------------------------------------------+
   32.29   *
   32.30 @@ -58,21 +58,6 @@
   32.31  /* number of pages to write at a time */
   32.32  #define DUMP_INCREMENT (4 * 1024)
   32.33  
   32.34 -static int
   32.35 -copy_from_domain_page(int xc_handle,
   32.36 -                      uint32_t domid,
   32.37 -                      unsigned long mfn,
   32.38 -                      void *dst_page)
   32.39 -{
   32.40 -    void *vaddr = xc_map_foreign_range(
   32.41 -        xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
   32.42 -    if ( vaddr == NULL )
   32.43 -        return -1;
   32.44 -    memcpy(dst_page, vaddr, PAGE_SIZE);
   32.45 -    munmap(vaddr, PAGE_SIZE);
   32.46 -    return 0;
   32.47 -}
   32.48 -
   32.49  /* string table */
   32.50  struct xc_core_strtab {
   32.51      char       *strings;
   32.52 @@ -231,6 +216,35 @@ xc_core_shdr_set(Elf64_Shdr *shdr,
   32.53      return 0;
   32.54  }
   32.55  
   32.56 +static void
   32.57 +xc_core_ehdr_init(Elf64_Ehdr *ehdr)
   32.58 +{
   32.59 +    memset(ehdr, 0, sizeof(*ehdr));
   32.60 +    ehdr->e_ident[EI_MAG0] = ELFMAG0;
   32.61 +    ehdr->e_ident[EI_MAG1] = ELFMAG1;
   32.62 +    ehdr->e_ident[EI_MAG2] = ELFMAG2;
   32.63 +    ehdr->e_ident[EI_MAG3] = ELFMAG3;
   32.64 +    ehdr->e_ident[EI_CLASS] = ELFCLASS64;
   32.65 +    ehdr->e_ident[EI_DATA] = ELF_ARCH_DATA;
   32.66 +    ehdr->e_ident[EI_VERSION] = EV_CURRENT;
   32.67 +    ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
   32.68 +    ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT;
   32.69 +
   32.70 +    ehdr->e_type = ET_CORE;
   32.71 +    ehdr->e_machine = ELF_ARCH_MACHINE;
   32.72 +    ehdr->e_version = EV_CURRENT;
   32.73 +    ehdr->e_entry = 0;
   32.74 +    ehdr->e_phoff = 0;
   32.75 +    ehdr->e_shoff = sizeof(*ehdr);
   32.76 +    ehdr->e_flags = ELF_CORE_EFLAGS;
   32.77 +    ehdr->e_ehsize = sizeof(*ehdr);
   32.78 +    ehdr->e_phentsize = sizeof(Elf64_Phdr);
   32.79 +    ehdr->e_phnum = 0;
   32.80 +    ehdr->e_shentsize = sizeof(Elf64_Shdr);
   32.81 +    /* ehdr->e_shnum and ehdr->e_shstrndx aren't known here yet.
   32.82 +     * fill it later */
   32.83 +}
   32.84 +
   32.85  static int
   32.86  elfnote_fill_xen_version(int xc_handle,
   32.87                           struct xen_dumpcore_elfnote_xen_version_desc
   32.88 @@ -277,12 +291,100 @@ elfnote_fill_xen_version(int xc_handle,
   32.89      return 0;
   32.90  }
   32.91  
   32.92 -static int
   32.93 +static void
   32.94  elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
   32.95                              *format_version)
   32.96  {
   32.97      format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
   32.98 -    return 0;
   32.99 +}
  32.100 +
  32.101 +static void
  32.102 +elfnote_init(struct elfnote *elfnote)
  32.103 +{
  32.104 +    /* elf note section */
  32.105 +    memset(elfnote, 0, sizeof(*elfnote));
  32.106 +    elfnote->namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
  32.107 +    strncpy(elfnote->name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote->name));
  32.108 +}
  32.109 +
  32.110 +static int
  32.111 +elfnote_dump_none(void *args, dumpcore_rtn_t dump_rtn)
  32.112 +{
  32.113 +    int sts;
  32.114 +    struct elfnote elfnote;
  32.115 +    struct xen_dumpcore_elfnote_none_desc none;
  32.116 +
  32.117 +    elfnote_init(&elfnote);
  32.118 +    memset(&none, 0, sizeof(none));
  32.119 +
  32.120 +    elfnote.descsz = sizeof(none);
  32.121 +    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
  32.122 +    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.123 +    if ( sts != 0 )
  32.124 +        return sts;
  32.125 +    return dump_rtn(args, (char*)&none, sizeof(none));
  32.126 +}
  32.127 +
  32.128 +static int
  32.129 +elfnote_dump_core_header(
  32.130 +    void *args, dumpcore_rtn_t dump_rtn, const xc_dominfo_t *info,
  32.131 +    int nr_vcpus, unsigned long nr_pages)
  32.132 +{
  32.133 +    int sts;
  32.134 +    struct elfnote elfnote;
  32.135 +    struct xen_dumpcore_elfnote_header_desc header;
  32.136 +    
  32.137 +    elfnote_init(&elfnote);
  32.138 +    memset(&header, 0, sizeof(header));
  32.139 +    
  32.140 +    elfnote.descsz = sizeof(header);
  32.141 +    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
  32.142 +    header.xch_magic = info->hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
  32.143 +    header.xch_nr_vcpus = nr_vcpus;
  32.144 +    header.xch_nr_pages = nr_pages;
  32.145 +    header.xch_page_size = PAGE_SIZE;
  32.146 +    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.147 +    if ( sts != 0 )
  32.148 +        return sts;
  32.149 +    return dump_rtn(args, (char*)&header, sizeof(header));
  32.150 +}
  32.151 +
  32.152 +static int
  32.153 +elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int xc_handle)
  32.154 +{
  32.155 +    int sts;
  32.156 +    struct elfnote elfnote;
  32.157 +    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
  32.158 +
  32.159 +    elfnote_init(&elfnote);
  32.160 +    memset(&xen_version, 0, sizeof(xen_version));
  32.161 +
  32.162 +    elfnote.descsz = sizeof(xen_version);
  32.163 +    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
  32.164 +    elfnote_fill_xen_version(xc_handle, &xen_version);
  32.165 +    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.166 +    if ( sts != 0 )
  32.167 +        return sts;
  32.168 +    return dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
  32.169 +}
  32.170 +
  32.171 +static int
  32.172 +elfnote_dump_format_version(void *args, dumpcore_rtn_t dump_rtn)
  32.173 +{
  32.174 +    int sts;
  32.175 +    struct elfnote elfnote;
  32.176 +    struct xen_dumpcore_elfnote_format_version_desc format_version;
  32.177 +
  32.178 +    elfnote_init(&elfnote);
  32.179 +    memset(&format_version, 0, sizeof(format_version));
  32.180 +    
  32.181 +    elfnote.descsz = sizeof(format_version);
  32.182 +    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
  32.183 +    elfnote_fill_format_version(&format_version);
  32.184 +    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.185 +    if ( sts != 0 )
  32.186 +        return sts;
  32.187 +    return dump_rtn(args, (char*)&format_version, sizeof(format_version));
  32.188  }
  32.189  
  32.190  int
  32.191 @@ -327,13 +429,6 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.192      struct xc_core_section_headers *sheaders = NULL;
  32.193      Elf64_Shdr *shdr;
  32.194  
  32.195 -    /* elf notes */
  32.196 -    struct elfnote elfnote;
  32.197 -    struct xen_dumpcore_elfnote_none_desc none;
  32.198 -    struct xen_dumpcore_elfnote_header_desc header;
  32.199 -    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
  32.200 -    struct xen_dumpcore_elfnote_format_version_desc format_version;
  32.201 -
  32.202      xc_core_arch_context_init(&arch_ctxt);
  32.203      if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
  32.204      {
  32.205 @@ -379,8 +474,9 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.206      }
  32.207  
  32.208      /* obtain memory map */
  32.209 -    sts = xc_core_arch_memory_map_get(xc_handle, &info, live_shinfo,
  32.210 -                                      &memory_map, &nr_memory_map);
  32.211 +    sts = xc_core_arch_memory_map_get(xc_handle, &arch_ctxt, &info,
  32.212 +                                      live_shinfo, &memory_map,
  32.213 +                                      &nr_memory_map);
  32.214      if ( sts != 0 )
  32.215          goto out;
  32.216  
  32.217 @@ -410,70 +506,8 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.218          }
  32.219      }
  32.220  
  32.221 -    /* create .xen_p2m or .xen_pfn */
  32.222 -    j = 0;
  32.223 -    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
  32.224 -    {
  32.225 -        uint64_t pfn_start;
  32.226 -        uint64_t pfn_end;
  32.227 -
  32.228 -        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
  32.229 -        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
  32.230 -        for ( i = pfn_start; i < pfn_end; i++ )
  32.231 -        {
  32.232 -            if ( !auto_translated_physmap )
  32.233 -            {
  32.234 -                if ( p2m[i] == INVALID_P2M_ENTRY )
  32.235 -                    continue;
  32.236 -                p2m_array[j].pfn = i;
  32.237 -                p2m_array[j].gmfn = p2m[i];
  32.238 -            }
  32.239 -            else
  32.240 -            {
  32.241 -                /* try to map page to determin wheter it has underlying page */
  32.242 -                void *vaddr = xc_map_foreign_range(xc_handle, domid,
  32.243 -                                                   PAGE_SIZE, PROT_READ, i);
  32.244 -                if ( vaddr == NULL )
  32.245 -                    continue;
  32.246 -                munmap(vaddr, PAGE_SIZE);
  32.247 -                pfn_array[j] = i;
  32.248 -            }
  32.249 -
  32.250 -            j++;
  32.251 -        }
  32.252 -    }
  32.253 -    if ( j != nr_pages )
  32.254 -    {
  32.255 -        PERROR("j (%ld) != nr_pages (%ld)", j , nr_pages);
  32.256 -        /* When live dump-mode (-L option) is specified,
  32.257 -         * guest domain may change its mapping.
  32.258 -         */
  32.259 -        nr_pages = j;
  32.260 -    }
  32.261 -
  32.262 -    memset(&ehdr, 0, sizeof(ehdr));
  32.263 -    ehdr.e_ident[EI_MAG0] = ELFMAG0;
  32.264 -    ehdr.e_ident[EI_MAG1] = ELFMAG1;
  32.265 -    ehdr.e_ident[EI_MAG2] = ELFMAG2;
  32.266 -    ehdr.e_ident[EI_MAG3] = ELFMAG3;
  32.267 -    ehdr.e_ident[EI_CLASS] = ELFCLASS64;
  32.268 -    ehdr.e_ident[EI_DATA] = ELF_ARCH_DATA;
  32.269 -    ehdr.e_ident[EI_VERSION] = EV_CURRENT;
  32.270 -    ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV;
  32.271 -    ehdr.e_ident[EI_ABIVERSION] = EV_CURRENT;
  32.272 -
  32.273 -    ehdr.e_type = ET_CORE;
  32.274 -    ehdr.e_machine = ELF_ARCH_MACHINE;
  32.275 -    ehdr.e_version = EV_CURRENT;
  32.276 -    ehdr.e_entry = 0;
  32.277 -    ehdr.e_phoff = 0;
  32.278 -    ehdr.e_shoff = sizeof(ehdr);
  32.279 -    ehdr.e_flags = ELF_CORE_EFLAGS;
  32.280 -    ehdr.e_ehsize = sizeof(ehdr);
  32.281 -    ehdr.e_phentsize = sizeof(Elf64_Phdr);
  32.282 -    ehdr.e_phnum = 0;
  32.283 -    ehdr.e_shentsize = sizeof(Elf64_Shdr);
  32.284      /* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
  32.285 +    xc_core_ehdr_init(&ehdr);
  32.286  
  32.287      /* create section header */
  32.288      strtab = xc_core_strtab_init();
  32.289 @@ -549,7 +583,7 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.290      /* arch context */
  32.291      sts = xc_core_arch_context_get_shdr(&arch_ctxt, sheaders, strtab,
  32.292                                          &filesz, offset);
  32.293 -    if ( sts != 0)
  32.294 +    if ( sts != 0 )
  32.295          goto out;
  32.296      offset += filesz;
  32.297  
  32.298 @@ -571,6 +605,33 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.299          offset += filesz;
  32.300      }
  32.301  
  32.302 +    /*
  32.303 +     * pages and p2m/pfn are the last section to allocate section headers
  32.304 +     * so that we know the number of section headers here.
  32.305 +     * 2 = pages section and p2m/pfn table section
  32.306 +     */
  32.307 +    fixup = (sheaders->num + 2) * sizeof(*shdr);
  32.308 +    /* zeroth section should have zero offset */
  32.309 +    for ( i = 1; i < sheaders->num; i++ )
  32.310 +        sheaders->shdrs[i].sh_offset += fixup;
  32.311 +    offset += fixup;
  32.312 +    dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
  32.313 +    offset += dummy_len;
  32.314 +
  32.315 +    /* pages */
  32.316 +    shdr = xc_core_shdr_get(sheaders);
  32.317 +    if ( shdr == NULL )
  32.318 +    {
  32.319 +        PERROR("could not get section headers for .xen_pages");
  32.320 +        goto out;
  32.321 +    }
  32.322 +    filesz = nr_pages * PAGE_SIZE;
  32.323 +    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
  32.324 +                           offset, filesz, PAGE_SIZE, PAGE_SIZE);
  32.325 +    if ( sts != 0 )
  32.326 +        goto out;
  32.327 +    offset += filesz;
  32.328 +
  32.329      /* p2m/pfn table */
  32.330      shdr = xc_core_shdr_get(sheaders);
  32.331      if ( shdr == NULL )
  32.332 @@ -585,8 +646,6 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.333                                 SHT_PROGBITS,
  32.334                                 offset, filesz, __alignof__(p2m_array[0]),
  32.335                                 sizeof(p2m_array[0]));
  32.336 -        if ( sts != 0 )
  32.337 -            goto out;
  32.338      }
  32.339      else
  32.340      {
  32.341 @@ -595,34 +654,7 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.342                                 SHT_PROGBITS,
  32.343                                 offset, filesz, __alignof__(pfn_array[0]),
  32.344                                 sizeof(pfn_array[0]));
  32.345 -        if ( sts != 0 )
  32.346 -            goto out;
  32.347      }
  32.348 -    offset += filesz;
  32.349 -
  32.350 -    /* pages */
  32.351 -    shdr = xc_core_shdr_get(sheaders);
  32.352 -    if ( shdr == NULL )
  32.353 -    {
  32.354 -        PERROR("could not get section headers for .xen_pages");
  32.355 -        goto out;
  32.356 -    }
  32.357 -
  32.358 -    /*
  32.359 -     * pages are the last section to allocate section headers
  32.360 -     * so that we know the number of section headers here.
  32.361 -     */
  32.362 -    fixup = sheaders->num * sizeof(*shdr);
  32.363 -    /* zeroth section should have zero offset */
  32.364 -    for ( i = 1; i < sheaders->num; i++ )
  32.365 -        sheaders->shdrs[i].sh_offset += fixup;
  32.366 -    offset += fixup;
  32.367 -    dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
  32.368 -    offset += dummy_len;
  32.369 -
  32.370 -    filesz = nr_pages * PAGE_SIZE;
  32.371 -    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
  32.372 -                           offset, filesz, PAGE_SIZE, PAGE_SIZE);
  32.373      if ( sts != 0 )
  32.374          goto out;
  32.375      offset += filesz;
  32.376 @@ -645,54 +677,23 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.377      if ( sts != 0 )
  32.378          goto out;
  32.379  
  32.380 -    /* elf note section */
  32.381 -    memset(&elfnote, 0, sizeof(elfnote));
  32.382 -    elfnote.namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
  32.383 -    strncpy(elfnote.name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote.name));
  32.384 -
  32.385 -    /* elf note section:xen core header */
  32.386 -    elfnote.descsz = sizeof(none);
  32.387 -    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
  32.388 -    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.389 -    if ( sts != 0 )
  32.390 -        goto out;
  32.391 -    sts = dump_rtn(args, (char*)&none, sizeof(none));
  32.392 +    /* elf note section: xen core header */
  32.393 +    sts = elfnote_dump_none(args, dump_rtn);
  32.394      if ( sts != 0 )
  32.395          goto out;
  32.396  
  32.397 -    /* elf note section:xen core header */
  32.398 -    elfnote.descsz = sizeof(header);
  32.399 -    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
  32.400 -    header.xch_magic = info.hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
  32.401 -    header.xch_nr_vcpus = nr_vcpus;
  32.402 -    header.xch_nr_pages = nr_pages;
  32.403 -    header.xch_page_size = PAGE_SIZE;
  32.404 -    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.405 -    if ( sts != 0 )
  32.406 -        goto out;
  32.407 -    sts = dump_rtn(args, (char*)&header, sizeof(header));
  32.408 +    /* elf note section: xen core header */
  32.409 +    sts = elfnote_dump_core_header(args, dump_rtn, &info, nr_vcpus, nr_pages);
  32.410      if ( sts != 0 )
  32.411          goto out;
  32.412  
  32.413      /* elf note section: xen version */
  32.414 -    elfnote.descsz = sizeof(xen_version);
  32.415 -    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
  32.416 -    elfnote_fill_xen_version(xc_handle, &xen_version);
  32.417 -    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.418 -    if ( sts != 0 )
  32.419 -        goto out;
  32.420 -    sts = dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
  32.421 +    sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle);
  32.422      if ( sts != 0 )
  32.423          goto out;
  32.424  
  32.425      /* elf note section: format version */
  32.426 -    elfnote.descsz = sizeof(format_version);
  32.427 -    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
  32.428 -    elfnote_fill_format_version(&format_version);
  32.429 -    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
  32.430 -    if ( sts != 0 )
  32.431 -        goto out;
  32.432 -    sts = dump_rtn(args, (char*)&format_version, sizeof(format_version));
  32.433 +    sts = elfnote_dump_format_version(args, dump_rtn);
  32.434      if ( sts != 0 )
  32.435          goto out;
  32.436  
  32.437 @@ -714,16 +715,6 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.438      if ( sts != 0 )
  32.439          goto out;
  32.440  
  32.441 -    /* p2m/pfn table: .xen_p2m/.xen_pfn */
  32.442 -    if ( !auto_translated_physmap )
  32.443 -        sts = dump_rtn(args, (char *)p2m_array,
  32.444 -                       sizeof(p2m_array[0]) * nr_pages);
  32.445 -    else
  32.446 -        sts = dump_rtn(args, (char *)pfn_array,
  32.447 -                       sizeof(pfn_array[0]) * nr_pages);
  32.448 -    if ( sts != 0 )
  32.449 -        goto out;
  32.450 -
  32.451      /* Pad the output data to page alignment. */
  32.452      memset(dummy, 0, PAGE_SIZE);
  32.453      sts = dump_rtn(args, dummy, dummy_len);
  32.454 @@ -731,25 +722,103 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.455          goto out;
  32.456  
  32.457      /* dump pages: .xen_pages */
  32.458 -    for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
  32.459 +    j = 0;
  32.460 +    dump_mem = dump_mem_start;
  32.461 +    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
  32.462      {
  32.463 -        uint64_t gmfn;
  32.464 -        if ( !auto_translated_physmap )
  32.465 -            gmfn = p2m_array[i].gmfn;
  32.466 -        else
  32.467 -            gmfn = pfn_array[i];
  32.468 +        uint64_t pfn_start;
  32.469 +        uint64_t pfn_end;
  32.470 +
  32.471 +        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
  32.472 +        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
  32.473 +        for ( i = pfn_start; i < pfn_end; i++ )
  32.474 +        {
  32.475 +            uint64_t gmfn;
  32.476 +            void *vaddr;
  32.477 +            
  32.478 +            if ( j >= nr_pages )
  32.479 +            {
  32.480 +                /*
  32.481 +                 * When live dump-mode (-L option) is specified,
  32.482 +                 * guest domain may increase memory.
  32.483 +                 */
  32.484 +                IPRINTF("exceeded nr_pages (%ld) losing pages", nr_pages);
  32.485 +                goto copy_done;
  32.486 +            }
  32.487 +
  32.488 +            if ( !auto_translated_physmap )
  32.489 +            {
  32.490 +                gmfn = p2m[i];
  32.491 +                if ( gmfn == INVALID_P2M_ENTRY )
  32.492 +                    continue;
  32.493 +
  32.494 +                p2m_array[j].pfn = i;
  32.495 +                p2m_array[j].gmfn = gmfn;
  32.496 +            }
  32.497 +            else
  32.498 +            {
  32.499 +                if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
  32.500 +                    continue;
  32.501  
  32.502 -        copy_from_domain_page(xc_handle, domid, gmfn, dump_mem);
  32.503 -        dump_mem += PAGE_SIZE;
  32.504 -        if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
  32.505 -        {
  32.506 -            sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
  32.507 +                gmfn = i;
  32.508 +                pfn_array[j] = i;
  32.509 +            }
  32.510 +
  32.511 +            vaddr = xc_map_foreign_range(
  32.512 +                xc_handle, domid, PAGE_SIZE, PROT_READ, gmfn);
  32.513 +            if ( vaddr == NULL )
  32.514 +                continue;
  32.515 +            memcpy(dump_mem, vaddr, PAGE_SIZE);
  32.516 +            munmap(vaddr, PAGE_SIZE);
  32.517 +            dump_mem += PAGE_SIZE;
  32.518 +            if ( (j + 1) % DUMP_INCREMENT == 0 )
  32.519 +            {
  32.520 +                sts = dump_rtn(
  32.521 +                    args, dump_mem_start, dump_mem - dump_mem_start);
  32.522 +                if ( sts != 0 )
  32.523 +                    goto out;
  32.524 +                dump_mem = dump_mem_start;
  32.525 +            }
  32.526 +
  32.527 +            j++;
  32.528 +        }
  32.529 +    }
  32.530 +
  32.531 +copy_done:
  32.532 +    sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
  32.533 +    if ( sts != 0 )
  32.534 +        goto out;
  32.535 +    if ( j < nr_pages )
  32.536 +    {
  32.537 +        /* When live dump-mode (-L option) is specified,
  32.538 +         * guest domain may reduce memory. pad with zero pages.
  32.539 +         */
  32.540 +        IPRINTF("j (%ld) != nr_pages (%ld)", j , nr_pages);
  32.541 +        memset(dump_mem_start, 0, PAGE_SIZE);
  32.542 +        for (; j < nr_pages; j++) {
  32.543 +            sts = dump_rtn(args, dump_mem_start, PAGE_SIZE);
  32.544              if ( sts != 0 )
  32.545                  goto out;
  32.546 -            dump_mem = dump_mem_start;
  32.547 +            if ( !auto_translated_physmap )
  32.548 +            {
  32.549 +                p2m_array[j].pfn = XC_CORE_INVALID_PFN;
  32.550 +                p2m_array[j].gmfn = XC_CORE_INVALID_GMFN;
  32.551 +            }
  32.552 +            else
  32.553 +                pfn_array[j] = XC_CORE_INVALID_PFN;
  32.554          }
  32.555      }
  32.556  
  32.557 +    /* p2m/pfn table: .xen_p2m/.xen_pfn */
  32.558 +    if ( !auto_translated_physmap )
  32.559 +        sts = dump_rtn(
  32.560 +            args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
  32.561 +    else
  32.562 +        sts = dump_rtn(
  32.563 +            args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
  32.564 +    if ( sts != 0 )
  32.565 +        goto out;
  32.566 +
  32.567      /* elf section header string table: .shstrtab */
  32.568      sts = dump_rtn(args, strtab->strings, strtab->current);
  32.569      if ( sts != 0 )
  32.570 @@ -758,6 +827,8 @@ xc_domain_dumpcore_via_callback(int xc_h
  32.571      sts = 0;
  32.572  
  32.573  out:
  32.574 +    if ( memory_map != NULL )
  32.575 +        free(memory_map);
  32.576      if ( p2m != NULL )
  32.577          munmap(p2m, PAGE_SIZE * P2M_FL_ENTRIES);
  32.578      if ( p2m_array != NULL )
    33.1 --- a/tools/libxc/xc_core.h	Thu Sep 06 09:05:26 2007 -0600
    33.2 +++ b/tools/libxc/xc_core.h	Thu Sep 06 12:05:15 2007 -0600
    33.3 @@ -107,6 +107,8 @@ struct xen_dumpcore_elfnote_format_versi
    33.4      struct xen_dumpcore_elfnote_format_version_desc     format_version;
    33.5  };
    33.6  
    33.7 +#define XC_CORE_INVALID_PFN     (~(uint64_t)0)
    33.8 +#define XC_CORE_INVALID_GMFN    (~(uint64_t)0)
    33.9  struct xen_dumpcore_p2m {
   33.10      uint64_t    pfn;
   33.11      uint64_t    gmfn;
   33.12 @@ -131,8 +133,10 @@ struct xc_core_memory_map {
   33.13  };
   33.14  typedef struct xc_core_memory_map xc_core_memory_map_t;
   33.15  int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info);
   33.16 -int xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
   33.17 -                                shared_info_t *live_shinfo,
   33.18 +struct xc_core_arch_context;
   33.19 +int xc_core_arch_memory_map_get(int xc_handle,
   33.20 +                                struct xc_core_arch_context *arch_ctxt,
   33.21 +                                xc_dominfo_t *info, shared_info_t *live_shinfo,
   33.22                                  xc_core_memory_map_t **mapp,
   33.23                                  unsigned int *nr_entries);
   33.24  int xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
    34.1 --- a/tools/libxc/xc_core_ia64.c	Thu Sep 06 09:05:26 2007 -0600
    34.2 +++ b/tools/libxc/xc_core_ia64.c	Thu Sep 06 12:05:15 2007 -0600
    34.3 @@ -158,8 +158,8 @@ memory_map_get_old(int xc_handle, xc_dom
    34.4  }
    34.5  
    34.6  int
    34.7 -xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
    34.8 -                            shared_info_t *live_shinfo,
    34.9 +xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
   34.10 +                            xc_dominfo_t *info, shared_info_t *live_shinfo,
   34.11                              xc_core_memory_map_t **mapp,
   34.12                              unsigned int *nr_entries)
   34.13  {
    35.1 --- a/tools/libxc/xc_core_ia64.h	Thu Sep 06 09:05:26 2007 -0600
    35.2 +++ b/tools/libxc/xc_core_ia64.h	Thu Sep 06 12:05:15 2007 -0600
    35.3 @@ -46,6 +46,7 @@ xc_core_arch_context_get_shdr(struct xc_
    35.4  int
    35.5  xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
    35.6                            void* args, dumpcore_rtn_t dump_rtn);
    35.7 +#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
    35.8  
    35.9  #endif /* XC_CORE_IA64_H */
   35.10  
    36.1 --- a/tools/libxc/xc_core_powerpc.c	Thu Sep 06 09:05:26 2007 -0600
    36.2 +++ b/tools/libxc/xc_core_powerpc.c	Thu Sep 06 12:05:15 2007 -0600
    36.3 @@ -43,8 +43,8 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
    36.4  }
    36.5  
    36.6  int
    36.7 -xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
    36.8 -                            shared_info_t *live_shinfo,
    36.9 +xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
   36.10 +                            xc_dominfo_t *info, shared_info_t *live_shinfo,
   36.11                              xc_core_memory_map_t **mapp,
   36.12                              unsigned int *nr_entries)
   36.13  {
    37.1 --- a/tools/libxc/xc_core_powerpc.h	Thu Sep 06 09:05:26 2007 -0600
    37.2 +++ b/tools/libxc/xc_core_powerpc.h	Thu Sep 06 12:05:15 2007 -0600
    37.3 @@ -33,6 +33,7 @@ struct xc_core_arch_context {
    37.4  #define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
    37.5                                                                  (0)
    37.6  #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
    37.7 +#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
    37.8  
    37.9  static inline int
   37.10  xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
    38.1 --- a/tools/libxc/xc_core_x86.c	Thu Sep 06 09:05:26 2007 -0600
    38.2 +++ b/tools/libxc/xc_core_x86.c	Thu Sep 06 12:05:15 2007 -0600
    38.3 @@ -33,8 +33,8 @@ xc_core_arch_auto_translated_physmap(con
    38.4  }
    38.5  
    38.6  int
    38.7 -xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
    38.8 -                            shared_info_t *live_shinfo,
    38.9 +xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
   38.10 +                            xc_dominfo_t *info, shared_info_t *live_shinfo,
   38.11                              xc_core_memory_map_t **mapp,
   38.12                              unsigned int *nr_entries)
   38.13  {
    39.1 --- a/tools/libxc/xc_core_x86.h	Thu Sep 06 09:05:26 2007 -0600
    39.2 +++ b/tools/libxc/xc_core_x86.h	Thu Sep 06 12:05:15 2007 -0600
    39.3 @@ -40,6 +40,7 @@ struct xc_core_arch_context {
    39.4  #define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
    39.5                                                                  (0)
    39.6  #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
    39.7 +#define xc_core_arch_gpfn_may_present(arch_ctxt, i)             (1)
    39.8  
    39.9  static inline int
   39.10  xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
    40.1 --- a/tools/libxc/xc_domain.c	Thu Sep 06 09:05:26 2007 -0600
    40.2 +++ b/tools/libxc/xc_domain.c	Thu Sep 06 12:05:15 2007 -0600
    40.3 @@ -55,10 +55,14 @@ int xc_domain_unpause(int xc_handle,
    40.4  int xc_domain_destroy(int xc_handle,
    40.5                        uint32_t domid)
    40.6  {
    40.7 +    int ret;
    40.8      DECLARE_DOMCTL;
    40.9      domctl.cmd = XEN_DOMCTL_destroydomain;
   40.10      domctl.domain = (domid_t)domid;
   40.11 -    return do_domctl(xc_handle, &domctl);
   40.12 +    do {
   40.13 +        ret = do_domctl(xc_handle, &domctl);
   40.14 +    } while ( ret && (errno == EAGAIN) );
   40.15 +    return ret;
   40.16  }
   40.17  
   40.18  int xc_domain_shutdown(int xc_handle,
    41.1 --- a/tools/libxc/xenctrl.h	Thu Sep 06 09:05:26 2007 -0600
    41.2 +++ b/tools/libxc/xenctrl.h	Thu Sep 06 12:05:15 2007 -0600
    41.3 @@ -26,8 +26,8 @@
    41.4  #include <xen/event_channel.h>
    41.5  #include <xen/sched.h>
    41.6  #include <xen/memory.h>
    41.7 -#include <xen/acm.h>
    41.8 -#include <xen/acm_ops.h>
    41.9 +#include <xen/xsm/acm.h>
   41.10 +#include <xen/xsm/acm_ops.h>
   41.11  
   41.12  #ifdef __ia64__
   41.13  #define XC_PAGE_SHIFT           14
    42.1 --- a/tools/misc/xenperf.c	Thu Sep 06 09:05:26 2007 -0600
    42.2 +++ b/tools/misc/xenperf.c	Thu Sep 06 12:05:15 2007 -0600
    42.3 @@ -46,7 +46,7 @@ const char *hypercall_name_table[64] =
    42.4      X(vcpu_op),
    42.5      X(set_segment_base),
    42.6      X(mmuext_op),
    42.7 -    X(acm_op),
    42.8 +    X(xsm_op),
    42.9      X(nmi_op),
   42.10      X(sched_op),
   42.11      X(callback_op),
    43.1 --- a/tools/python/Makefile	Thu Sep 06 09:05:26 2007 -0600
    43.2 +++ b/tools/python/Makefile	Thu Sep 06 12:05:15 2007 -0600
    43.3 @@ -1,6 +1,14 @@
    43.4  XEN_ROOT = ../..
    43.5  include $(XEN_ROOT)/tools/Rules.mk
    43.6  
    43.7 +XEN_SECURITY_MODULE = dummy
    43.8 +ifeq ($(FLASK_ENABLE),y)
    43.9 +XEN_SECURITY_MODULE = flask
   43.10 +endif
   43.11 +ifeq ($(ACM_SECURITY),y)
   43.12 +XEN_SECURITY_MODULE = acm
   43.13 +endif
   43.14 +
   43.15  .PHONY: all
   43.16  all: build
   43.17  
   43.18 @@ -15,8 +23,8 @@ CATALOGS = $(patsubst %,xen/xm/messages/
   43.19  NLSDIR = /usr/share/locale
   43.20  
   43.21  .PHONY: build buildpy
   43.22 -buildpy:
   43.23 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build
   43.24 +buildpy: xsm.py
   43.25 +	CC="$(CC)" CFLAGS="$(CFLAGS)" XEN_SECURITY_MODULE="$(XEN_SECURITY_MODULE)" python setup.py build
   43.26  
   43.27  build: buildpy refresh-pot refresh-po $(CATALOGS)
   43.28  
   43.29 @@ -53,6 +61,18 @@ refresh-po: $(POTFILE)
   43.30  %.mo: %.po
   43.31  	$(MSGFMT) -c -o $@ $<
   43.32  
   43.33 +xsm.py:
   43.34 +	@(set -e; \
   43.35 +	  echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \
   43.36 +	  echo "from xsm_core import *"; \
   43.37 +	  echo ""; \
   43.38 +	  echo "import xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" as xsm_module"; \
   43.39 +	  echo ""; \
   43.40 +	  echo "xsm_init(xsm_module)"; \
   43.41 +	  echo "from xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" import *"; \
   43.42 +	  echo "del xsm_module"; \
   43.43 +	  echo "") >xen/util/xsm/$@
   43.44 +
   43.45  .PHONY: install
   43.46  ifndef XEN_PYTHON_NATIVE_INSTALL
   43.47  install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()")
   43.48 @@ -84,4 +104,4 @@ test:
   43.49  
   43.50  .PHONY: clean
   43.51  clean:
   43.52 -	rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS)
   43.53 +	rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/xsm/xsm.py
    44.1 --- a/tools/python/setup.py	Thu Sep 06 09:05:26 2007 -0600
    44.2 +++ b/tools/python/setup.py	Thu Sep 06 12:05:15 2007 -0600
    44.3 @@ -44,6 +44,14 @@ acm = Extension("acm",
    44.4                 libraries          = libraries,
    44.5                 sources            = [ "xen/lowlevel/acm/acm.c" ])
    44.6  
    44.7 +flask = Extension("flask",
    44.8 +               extra_compile_args = extra_compile_args,
    44.9 +               include_dirs       = include_dirs + [ "xen/lowlevel/flask" ] + 
   44.10 +                                        [ "../flask/libflask/include" ],
   44.11 +               library_dirs       = library_dirs + [ "../flask/libflask" ],
   44.12 +               libraries          = libraries + [ "flask" ],
   44.13 +               sources            = [ "xen/lowlevel/flask/flask.c" ])
   44.14 +
   44.15  ptsname = Extension("ptsname",
   44.16                 extra_compile_args = extra_compile_args,
   44.17                 include_dirs       = include_dirs + [ "ptsname" ],
   44.18 @@ -51,7 +59,7 @@ ptsname = Extension("ptsname",
   44.19                 libraries          = libraries,
   44.20                 sources            = [ "ptsname/ptsname.c" ])
   44.21  
   44.22 -modules = [ xc, xs, acm, ptsname ]
   44.23 +modules = [ xc, xs, ptsname, acm, flask ]
   44.24  if os.uname()[0] == 'SunOS':
   44.25      modules.append(scf)
   44.26  
   44.27 @@ -61,6 +69,10 @@ setup(name            = 'xen',
   44.28        packages        = ['xen',
   44.29                           'xen.lowlevel',
   44.30                           'xen.util',
   44.31 +                         'xen.util.xsm',
   44.32 +                         'xen.util.xsm.dummy',
   44.33 +                         'xen.util.xsm.flask',
   44.34 +                         'xen.util.xsm.acm',
   44.35                           'xen.xend',
   44.36                           'xen.xend.server',
   44.37                           'xen.xend.xenstore',
    45.1 --- a/tools/python/xen/lowlevel/acm/acm.c	Thu Sep 06 09:05:26 2007 -0600
    45.2 +++ b/tools/python/xen/lowlevel/acm/acm.c	Thu Sep 06 12:05:15 2007 -0600
    45.3 @@ -18,6 +18,7 @@
    45.4   *
    45.5   * indent -i4 -kr -nut
    45.6   */
    45.7 +
    45.8  #include <Python.h>
    45.9  
   45.10  #include <stdio.h>
   45.11 @@ -27,8 +28,8 @@
   45.12  #include <stdlib.h>
   45.13  #include <sys/ioctl.h>
   45.14  #include <netinet/in.h>
   45.15 -#include <xen/acm.h>
   45.16 -#include <xen/acm_ops.h>
   45.17 +#include <xen/xsm/acm.h>
   45.18 +#include <xen/xsm/acm_ops.h>
   45.19  
   45.20  #include <xenctrl.h>
   45.21  
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/python/xen/lowlevel/flask/flask.c	Thu Sep 06 12:05:15 2007 -0600
    46.3 @@ -0,0 +1,139 @@
    46.4 +/******************************************************************************
    46.5 + * flask.c
    46.6 + * 
    46.7 + * Authors: George Coker, <gscoker@alpha.ncsc.mil>
    46.8 + *          Michael LeMay, <mdlemay@epoch.ncsc.mil>
    46.9 + *
   46.10 + *
   46.11 + *    This program is free software; you can redistribute it and/or modify
   46.12 + *    it under the terms of the GNU General Public License version 2,
   46.13 + *    as published by the Free Software Foundation.
   46.14 + */
   46.15 +
   46.16 +#include <Python.h>
   46.17 +#include <xenctrl.h>
   46.18 +
   46.19 +#include <flask_op.h>
   46.20 +
   46.21 +#define PKG "xen.lowlevel.flask"
   46.22 +#define CLS "flask"
   46.23 +
   46.24 +#define CTX_LEN 1024
   46.25 +
   46.26 +static PyObject *xc_error_obj;
   46.27 +
   46.28 +typedef struct {
   46.29 +    PyObject_HEAD;
   46.30 +    int xc_handle;
   46.31 +} XcObject;
   46.32 +
   46.33 +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
   46.34 +                                                                 PyObject *kwds)
   46.35 +{
   46.36 +    int xc_handle;
   46.37 +    char *ctx;
   46.38 +    char *buf;
   46.39 +    uint32_t len;
   46.40 +    uint32_t sid;
   46.41 +    int ret;
   46.42 +
   46.43 +    static char *kwd_list[] = { "context", NULL };
   46.44 +
   46.45 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list,
   46.46 +                                      &ctx) )
   46.47 +        return NULL;
   46.48 +
   46.49 +    len = strlen(ctx);
   46.50 +
   46.51 +    buf = malloc(len);
   46.52 +    if (!buf) {
   46.53 +        errno = -ENOMEM;
   46.54 +        PyErr_SetFromErrno(xc_error_obj);
   46.55 +    }
   46.56 +    
   46.57 +    memcpy(buf, ctx, len);
   46.58 +    
   46.59 +    xc_handle = xc_interface_open();
   46.60 +    if (xc_handle < 0) {
   46.61 +        errno = xc_handle;
   46.62 +        return PyErr_SetFromErrno(xc_error_obj);
   46.63 +    }
   46.64 +    
   46.65 +    ret = flask_context_to_sid(xc_handle, buf, len, &sid);
   46.66 +        
   46.67 +    xc_interface_close(xc_handle);
   46.68 +
   46.69 +    free(buf);
   46.70 +    
   46.71 +    if ( ret != 0 ) {
   46.72 +        errno = -ret;
   46.73 +        return PyErr_SetFromErrno(xc_error_obj);
   46.74 +    }
   46.75 +
   46.76 +    return PyInt_FromLong(sid);
   46.77 +}
   46.78 +
   46.79 +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args,
   46.80 +                                                                 PyObject *kwds)
   46.81 +{
   46.82 +    int xc_handle;
   46.83 +    uint32_t sid;
   46.84 +    char ctx[CTX_LEN];
   46.85 +    uint32_t ctx_len = CTX_LEN;
   46.86 +    int ret;
   46.87 +
   46.88 +    static char *kwd_list[] = { "sid", NULL };
   46.89 +
   46.90 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
   46.91 +                                      &sid) )
   46.92 +        return NULL;
   46.93 +
   46.94 +    xc_handle = xc_interface_open();
   46.95 +    if (xc_handle < 0) {
   46.96 +        errno = xc_handle;
   46.97 +        return PyErr_SetFromErrno(xc_error_obj);
   46.98 +    }
   46.99 +    
  46.100 +    ret = flask_sid_to_context(xc_handle, sid, ctx, ctx_len);
  46.101 +    
  46.102 +    xc_interface_close(xc_handle);
  46.103 +    
  46.104 +    if ( ret != 0 ) {
  46.105 +        errno = -ret;
  46.106 +        return PyErr_SetFromErrno(xc_error_obj);
  46.107 +    }
  46.108 +
  46.109 +    return Py_BuildValue("s", ctx, ctx_len);
  46.110 +}
  46.111 +
  46.112 +
  46.113 +static PyMethodDef pyflask_methods[] = {
  46.114 +    { "flask_context_to_sid",
  46.115 +      (PyCFunction)pyflask_context_to_sid,
  46.116 +      METH_KEYWORDS, "\n"
  46.117 +      "Convert a context string to a dynamic SID.\n"
  46.118 +      " context [str]: String specifying context to be converted\n"
  46.119 +      "Returns: [int]: Numeric SID on success; -1 on error.\n" },
  46.120 +
  46.121 +    { "flask_sid_to_context",
  46.122 +      (PyCFunction)pyflask_sid_to_context,
  46.123 +      METH_KEYWORDS, "\n"
  46.124 +      "Convert a dynamic SID to context string.\n"
  46.125 +      " context [int]: SID to be converted\n"
  46.126 +      "Returns: [str]: Numeric SID on success; -1 on error.\n" },
  46.127 +
  46.128 +    { NULL, NULL, 0, NULL }
  46.129 +};
  46.130 +
  46.131 +PyMODINIT_FUNC initflask(void)
  46.132 +{
  46.133 +    Py_InitModule("flask", pyflask_methods);
  46.134 +}
  46.135 +
  46.136 +
  46.137 +/*
  46.138 + * Local variables:
  46.139 + *  c-indent-level: 4
  46.140 + *  c-basic-offset: 4
  46.141 + * End:
  46.142 + */
    47.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 06 09:05:26 2007 -0600
    47.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 06 12:05:15 2007 -0600
    47.3 @@ -685,7 +685,7 @@ static PyObject *pyxc_physinfo(XcObject 
    47.4      char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
    47.5      int i, j, max_cpu_id;
    47.6      PyObject *ret_obj, *node_to_cpu_obj;
    47.7 -    xc_cpu_to_node_t map[MAX_CPU_ID];
    47.8 +    xc_cpu_to_node_t map[MAX_CPU_ID + 1];
    47.9  
   47.10      set_xen_guest_handle(info.cpu_to_node, map);
   47.11      info.max_cpu_id = MAX_CPU_ID;
    48.1 --- a/tools/python/xen/util/acmpolicy.py	Thu Sep 06 09:05:26 2007 -0600
    48.2 +++ b/tools/python/xen/util/acmpolicy.py	Thu Sep 06 12:05:15 2007 -0600
    48.3 @@ -1,4 +1,4 @@
    48.4 -#============================================================================
    48.5 + #============================================================================
    48.6  # This library is free software; you can redistribute it and/or
    48.7  # modify it under the terms of version 2.1 of the GNU Lesser General Public
    48.8  # License as published by the Free Software Foundation.
    48.9 @@ -23,10 +23,11 @@ import stat
   48.10  import array
   48.11  from xml.dom import minidom, Node
   48.12  from xen.xend.XendLogging import log
   48.13 -from xen.util import security, xsconstants, bootloader, mkdir
   48.14 +from xen.util import xsconstants, bootloader, mkdir
   48.15  from xen.util.xspolicy import XSPolicy
   48.16 -from xen.util.security import ACMError
   48.17  from xen.xend.XendError import SecurityError
   48.18 +import xen.util.xsm.acm.acm as security
   48.19 +from xen.util.xsm.xsm import XSMError
   48.20  
   48.21  ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
   48.22  
   48.23 @@ -1240,8 +1241,8 @@ class ACMPolicy(XSPolicy):
   48.24  
   48.25          (major, minor) = self.getVersionTuple()
   48.26          hdr_bin = struct.pack(headerformat,
   48.27 +                              ACM_MAGIC,
   48.28                                ACM_POLICY_VERSION,
   48.29 -                              ACM_MAGIC,
   48.30                                totallen_bin,
   48.31                                polref_offset,
   48.32                                primpolcode,
    49.1 --- a/tools/python/xen/util/security.py	Thu Sep 06 09:05:26 2007 -0600
    49.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.3 @@ -1,1299 +0,0 @@
    49.4 -#===========================================================================
    49.5 -# This library is free software; you can redistribute it and/or
    49.6 -# modify it under the terms of version 2.1 of the GNU Lesser General Public
    49.7 -# License as published by the Free Software Foundation.
    49.8 -#
    49.9 -# This library is distributed in the hope that it will be useful,
   49.10 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.11 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   49.12 -# Lesser General Public License for more details.
   49.13 -#
   49.14 -# You should have received a copy of the GNU Lesser General Public
   49.15 -# License along with this library; if not, write to the Free Software
   49.16 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   49.17 -#============================================================================
   49.18 -# Copyright (C) 2006 International Business Machines Corp.
   49.19 -# Author: Reiner Sailer
   49.20 -# Author: Bryan D. Payne <bdpayne@us.ibm.com>
   49.21 -# Author: Stefan Berger <stefanb@us.ibm.com>
   49.22 -#============================================================================
   49.23 -
   49.24 -import commands
   49.25 -import logging
   49.26 -import os, string, re
   49.27 -import threading
   49.28 -import struct
   49.29 -import stat
   49.30 -from xen.lowlevel import acm
   49.31 -from xen.xend import sxp
   49.32 -from xen.xend import XendConstants
   49.33 -from xen.xend.XendLogging import log
   49.34 -from xen.xend.XendError import VmError
   49.35 -from xen.util import dictio, xsconstants
   49.36 -from xen.xend.XendConstants import *
   49.37 -
   49.38 -#global directories and tools for security management
   49.39 -policy_dir_prefix = "/etc/xen/acm-security/policies"
   49.40 -res_label_filename = policy_dir_prefix + "/resource_labels"
   49.41 -boot_filename = "/boot/grub/menu.lst"
   49.42 -altboot_filename = "/boot/grub/grub.conf"
   49.43 -xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
   49.44 -xensec_tool = "/usr/sbin/xensec_tool"
   49.45 -
   49.46 -#global patterns for map file
   49.47 -#police_reference_tagname = "POLICYREFERENCENAME"
   49.48 -primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
   49.49 -secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
   49.50 -label_template_re =  re.compile(".*security_label_template.xml", re.IGNORECASE)
   49.51 -mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
   49.52 -policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE)
   49.53 -vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
   49.54 -res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
   49.55 -all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
   49.56 -access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
   49.57 -
   49.58 -#global patterns for boot configuration file
   49.59 -xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
   49.60 -any_title_re = re.compile("\s*title\s", re.IGNORECASE)
   49.61 -xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
   49.62 -kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
   49.63 -any_module_re = re.compile("\s*module\s", re.IGNORECASE)
   49.64 -empty_line_re = re.compile("^\s*$")
   49.65 -binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
   49.66 -policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
   49.67 -
   49.68 -#decision hooks known to the hypervisor
   49.69 -ACMHOOK_sharing = 1
   49.70 -ACMHOOK_authorization = 2
   49.71 -
   49.72 -#other global variables
   49.73 -NULL_SSIDREF = 0
   49.74 -
   49.75 -#general Rlock for map files; only one lock for all mapfiles
   49.76 -__mapfile_lock = threading.RLock()
   49.77 -__resfile_lock = threading.RLock()
   49.78 -
   49.79 -log = logging.getLogger("xend.util.security")
   49.80 -
   49.81 -# Our own exception definition. It is masked (pass) if raised and
   49.82 -# whoever raises this exception must provide error information.
   49.83 -class ACMError(Exception):
   49.84 -    def __init__(self,value):
   49.85 -        self.value = value
   49.86 -    def __str__(self):
   49.87 -        return repr(self.value)
   49.88 -
   49.89 -
   49.90 -
   49.91 -def err(msg):
   49.92 -    """Raise ACM exception.
   49.93 -    """
   49.94 -    raise ACMError(msg)
   49.95 -
   49.96 -
   49.97 -
   49.98 -active_policy = None
   49.99 -
  49.100 -
  49.101 -def mapfile_lock():
  49.102 -    __mapfile_lock.acquire()
  49.103 -
  49.104 -def mapfile_unlock():
  49.105 -    __mapfile_lock.release()
  49.106 -
  49.107 -
  49.108 -def refresh_security_policy():
  49.109 -    """
  49.110 -    retrieves security policy
  49.111 -    """
  49.112 -    global active_policy
  49.113 -
  49.114 -    try:
  49.115 -        active_policy = acm.policy()
  49.116 -    except:
  49.117 -        active_policy = "INACTIVE"
  49.118 -
  49.119 -# now set active_policy
  49.120 -refresh_security_policy()
  49.121 -
  49.122 -def on():
  49.123 -    """
  49.124 -    returns none if security policy is off (not compiled),
  49.125 -    any string otherwise, use it: if not security.on() ...
  49.126 -    """
  49.127 -    refresh_security_policy()
  49.128 -    return (active_policy not in ['INACTIVE', 'NULL'])
  49.129 -
  49.130 -
  49.131 -def calc_dom_ssidref_from_info(info):
  49.132 -    """
  49.133 -       Calculate a domain's ssidref from the security_label in its
  49.134 -       info.
  49.135 -       This function is called before the domain is started and
  49.136 -       makes sure that:
  49.137 -        - the type of the policy is the same as indicated in the label
  49.138 -        - the name of the policy is the same as indicated in the label
  49.139 -        - calculates an up-to-date ssidref for the domain
  49.140 -       The latter is necessary since the domain's ssidref could have
  49.141 -       changed due to changes to the policy.
  49.142 -    """
  49.143 -    import xen.xend.XendConfig
  49.144 -    if isinstance(info, xen.xend.XendConfig.XendConfig):
  49.145 -        if info.has_key('security_label'):
  49.146 -            seclab = info['security_label']
  49.147 -            tmp = seclab.split(":")
  49.148 -            if len(tmp) != 3:
  49.149 -                raise VmError("VM label '%s' in wrong format." % seclab)
  49.150 -            typ, policyname, vmlabel = seclab.split(":")
  49.151 -            if typ != xsconstants.ACM_POLICY_ID:
  49.152 -                raise VmError("Policy type '%s' must be changed." % typ)
  49.153 -            refresh_security_policy()
  49.154 -            if active_policy != policyname:
  49.155 -                raise VmError("Active policy '%s' different than "
  49.156 -                              "what in VM's label ('%s')." %
  49.157 -                              (active_policy, policyname))
  49.158 -            ssidref = label2ssidref(vmlabel, policyname, "dom")
  49.159 -            return ssidref
  49.160 -        else:
  49.161 -            return 0x0
  49.162 -    raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
  49.163 -                  "not supported." % type(info))
  49.164 -
  49.165 -
  49.166 -def getmapfile(policyname):
  49.167 -    """
  49.168 -    in: if policyname is None then the currently
  49.169 -    active hypervisor policy is used
  49.170 -    out: 1. primary policy, 2. secondary policy,
  49.171 -    3. open file descriptor for mapping file, and
  49.172 -    4. True if policy file is available, False otherwise
  49.173 -    """
  49.174 -    if not policyname:
  49.175 -        policyname = active_policy
  49.176 -    map_file_ok = False
  49.177 -    primary = None
  49.178 -    secondary = None
  49.179 -    #strip last part of policy as file name part
  49.180 -    policy_dir_list = string.split(policyname, ".")
  49.181 -    policy_file = policy_dir_list.pop()
  49.182 -    if len(policy_dir_list) > 0:
  49.183 -        policy_dir = string.join(policy_dir_list, "/") + "/"
  49.184 -    else:
  49.185 -        policy_dir = ""
  49.186 -
  49.187 -    map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
  49.188 -    # check if it is there, if not check if policy file is there
  49.189 -    if not os.path.isfile(map_filename):
  49.190 -        policy_filename =  policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml"
  49.191 -        if not os.path.isfile(policy_filename):
  49.192 -            err("Policy file \'" + policy_filename + "\' not found.")
  49.193 -        else:
  49.194 -            err("Mapping file \'" + map_filename + "\' not found." +
  49.195 -                " Use xm makepolicy to create it.")
  49.196 -
  49.197 -    f = open(map_filename)
  49.198 -    for line in f:
  49.199 -        if policy_reference_entry_re.match(line):
  49.200 -            l = line.split()
  49.201 -            if (len(l) == 2) and (l[1] == policyname):
  49.202 -                map_file_ok = True
  49.203 -        elif primary_entry_re.match(line):
  49.204 -            l = line.split()
  49.205 -            if len(l) == 2:
  49.206 -                primary = l[1]
  49.207 -        elif secondary_entry_re.match(line):
  49.208 -            l = line.split()
  49.209 -            if len(l) == 2:
  49.210 -                secondary = l[1]
  49.211 -    f.close()
  49.212 -    f = open(map_filename)
  49.213 -    if map_file_ok and primary and secondary:
  49.214 -        return (primary, secondary, f, True)
  49.215 -    else:
  49.216 -        err("Mapping file inconsistencies found. Try makepolicy to create a new one.")
  49.217 -
  49.218 -
  49.219 -
  49.220 -def ssidref2label(ssidref_var):
  49.221 -    """
  49.222 -    returns labelname corresponding to ssidref;
  49.223 -    maps current policy to default directory
  49.224 -    to find mapping file
  49.225 -    """
  49.226 -    #1. translated permitted input formats
  49.227 -    if isinstance(ssidref_var, str):
  49.228 -        ssidref_var.strip()
  49.229 -        if ssidref_var[0:2] == "0x":
  49.230 -            ssidref = int(ssidref_var[2:], 16)
  49.231 -        else:
  49.232 -            ssidref = int(ssidref_var)
  49.233 -    elif isinstance(ssidref_var, int):
  49.234 -        ssidref = ssidref_var
  49.235 -    else:
  49.236 -        err("Instance type of ssidref not supported (must be of type 'str' or 'int')")
  49.237 -
  49.238 -    if ssidref == 0:
  49.239 -        from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  49.240 -        return ACM_LABEL_UNLABELED
  49.241 -
  49.242 -    try:
  49.243 -        mapfile_lock()
  49.244 -
  49.245 -        (primary, secondary, f, pol_exists) = getmapfile(None)
  49.246 -        if not f:
  49.247 -            if (pol_exists):
  49.248 -                err("Mapping file for policy not found.\n" +
  49.249 -                    "Please use makepolicy command to create mapping file!")
  49.250 -            else:
  49.251 -                err("Policy file for \'" + active_policy + "\' not found.")
  49.252 -
  49.253 -        #2. get labelnames for both ssidref parts
  49.254 -        pri_ssid = ssidref & 0xffff
  49.255 -        sec_ssid = ssidref >> 16
  49.256 -        pri_null_ssid = NULL_SSIDREF & 0xffff
  49.257 -        sec_null_ssid = NULL_SSIDREF >> 16
  49.258 -        pri_labels = []
  49.259 -        sec_labels = []
  49.260 -        labels = []
  49.261 -
  49.262 -        for line in f:
  49.263 -            l = line.split()
  49.264 -            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  49.265 -                continue
  49.266 -            if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
  49.267 -                pri_labels.append(l[3])
  49.268 -            if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid):
  49.269 -                sec_labels.append(l[3])
  49.270 -        f.close()
  49.271 -    finally:
  49.272 -        mapfile_unlock()
  49.273 -
  49.274 -    #3. get the label that is in both lists (combination must be a single label)
  49.275 -    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid):
  49.276 -        labels = sec_labels
  49.277 -    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid):
  49.278 -        labels = pri_labels
  49.279 -    elif secondary == "NULL":
  49.280 -        labels = pri_labels
  49.281 -    else:
  49.282 -        for i in pri_labels:
  49.283 -            for j in sec_labels:
  49.284 -                if (i==j):
  49.285 -                    labels.append(i)
  49.286 -    if len(labels) != 1:
  49.287 -        err("Label for ssidref \'" +  str(ssidref) +
  49.288 -            "\' unknown or not unique in policy \'" + active_policy + "\'")
  49.289 -
  49.290 -    return labels[0]
  49.291 -
  49.292 -
  49.293 -
  49.294 -def label2ssidref(labelname, policyname, typ):
  49.295 -    """
  49.296 -    returns ssidref corresponding to labelname;
  49.297 -    maps current policy to default directory
  49.298 -    to find mapping file    """
  49.299 -
  49.300 -    if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
  49.301 -        err("Cannot translate labels for \'" + policyname + "\' policy.")
  49.302 -
  49.303 -    allowed_types = ['ANY']
  49.304 -    if typ == 'dom':
  49.305 -        allowed_types.append('VM')
  49.306 -    elif typ == 'res':
  49.307 -        allowed_types.append('RES')
  49.308 -    else:
  49.309 -        err("Invalid type.  Must specify 'dom' or 'res'.")
  49.310 -
  49.311 -    try:
  49.312 -        mapfile_lock()
  49.313 -        (primary, secondary, f, pol_exists) = getmapfile(policyname)
  49.314 -
  49.315 -        #2. get labelnames for ssidref parts and find a common label
  49.316 -        pri_ssid = []
  49.317 -        sec_ssid = []
  49.318 -        for line in f:
  49.319 -            l = line.split()
  49.320 -            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  49.321 -                continue
  49.322 -            if primary and (l[1] in allowed_types) and \
  49.323 -                           (l[2] == primary) and \
  49.324 -                           (l[3] == labelname):
  49.325 -                pri_ssid.append(int(l[4], 16))
  49.326 -            if secondary and (l[1] in allowed_types) and \
  49.327 -                             (l[2] == secondary) and \
  49.328 -                             (l[3] == labelname):
  49.329 -                sec_ssid.append(int(l[4], 16))
  49.330 -        f.close()
  49.331 -        if (typ == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
  49.332 -            pri_ssid.append(NULL_SSIDREF)
  49.333 -        elif (typ == 'res') and (secondary == "CHWALL") and \
  49.334 -             (len(sec_ssid) == 0):
  49.335 -            sec_ssid.append(NULL_SSIDREF)
  49.336 -
  49.337 -        #3. sanity check and composition of ssidref
  49.338 -        if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and \
  49.339 -            (secondary != "NULL")):
  49.340 -            err("Label \'" + labelname + "\' not found.")
  49.341 -        elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
  49.342 -            err("Label \'" + labelname + "\' not unique in policy (policy error)")
  49.343 -        if secondary == "NULL":
  49.344 -            return pri_ssid[0]
  49.345 -        else:
  49.346 -            return (sec_ssid[0] << 16) | pri_ssid[0]
  49.347 -    finally:
  49.348 -       mapfile_unlock()
  49.349 -
  49.350 -
  49.351 -def refresh_ssidref(config):
  49.352 -    """
  49.353 -    looks up ssidref from security field
  49.354 -    and refreshes the value if label exists
  49.355 -    """
  49.356 -    #called by dom0, policy could have changed after xen.utils.security was initialized
  49.357 -    refresh_security_policy()
  49.358 -
  49.359 -    security = None
  49.360 -    if isinstance(config, dict):
  49.361 -        security = config['security']
  49.362 -    elif isinstance(config, list):
  49.363 -        security = sxp.child_value(config, 'security')
  49.364 -    else:
  49.365 -        err("Instance type of config parameter not supported.")
  49.366 -    if not security:
  49.367 -        #nothing to do (no security label attached)
  49.368 -        return config
  49.369 -
  49.370 -    policyname = None
  49.371 -    labelname = None
  49.372 -    # compose new security field
  49.373 -    for idx in range(0, len(security)):
  49.374 -        if security[idx][0] == 'ssidref':
  49.375 -            security.pop(idx)
  49.376 -            break
  49.377 -        elif security[idx][0] == 'access_control':
  49.378 -            for jdx in [1, 2]:
  49.379 -                if security[idx][jdx][0] == 'label':
  49.380 -                    labelname = security[idx][jdx][1]
  49.381 -                elif security[idx][jdx][0] == 'policy':
  49.382 -                    policyname = security[idx][jdx][1]
  49.383 -                else:
  49.384 -                    err("Illegal field in access_control")
  49.385 -    #verify policy is correct
  49.386 -    if active_policy != policyname:
  49.387 -        err("Policy \'" + str(policyname) +
  49.388 -            "\' in label does not match active policy \'"
  49.389 -            + str(active_policy) +"\'!")
  49.390 -
  49.391 -    new_ssidref = label2ssidref(labelname, policyname, 'dom')
  49.392 -    if not new_ssidref:
  49.393 -        err("SSIDREF refresh failed!")
  49.394 -
  49.395 -    security.append([ 'ssidref',str(new_ssidref)])
  49.396 -    security = ['security', security ]
  49.397 -
  49.398 -    for idx in range(0,len(config)):
  49.399 -        if config[idx][0] == 'security':
  49.400 -            config.pop(idx)
  49.401 -            break
  49.402 -        config.append(security)
  49.403 -
  49.404 -
  49.405 -
  49.406 -def get_ssid(domain):
  49.407 -    """
  49.408 -    enables domains to retrieve the label / ssidref of a running domain
  49.409 -    """
  49.410 -    if not on():
  49.411 -        err("No policy active.")
  49.412 -
  49.413 -    if isinstance(domain, str):
  49.414 -        domain_int = int(domain)
  49.415 -    elif isinstance(domain, int):
  49.416 -        domain_int = domain
  49.417 -    else:
  49.418 -        err("Illegal parameter type.")
  49.419 -    try:
  49.420 -        ssid_info = acm.getssid(int(domain_int))
  49.421 -    except:
  49.422 -        err("Cannot determine security information.")
  49.423 -
  49.424 -    if active_policy in ["DEFAULT"]:
  49.425 -        label = "DEFAULT"
  49.426 -    else:
  49.427 -        label = ssidref2label(ssid_info["ssidref"])
  49.428 -    return(ssid_info["policyreference"],
  49.429 -           label,
  49.430 -           ssid_info["policytype"],
  49.431 -           ssid_info["ssidref"])
  49.432 -
  49.433 -
  49.434 -
  49.435 -def get_decision(arg1, arg2):
  49.436 -    """
  49.437 -    enables domains to retrieve access control decisions from
  49.438 -    the hypervisor Access Control Module.
  49.439 -    IN: args format = ['domid', id] or ['ssidref', ssidref]
  49.440 -    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
  49.441 -    """
  49.442 -
  49.443 -    if not on():
  49.444 -        err("No policy active.")
  49.445 -
  49.446 -    #translate labels before calling low-level function
  49.447 -    if arg1[0] == 'access_control':
  49.448 -        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'):
  49.449 -            err("Argument type not supported.")
  49.450 -        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
  49.451 -        arg1 = ['ssidref', str(ssidref)]
  49.452 -    if arg2[0] == 'access_control':
  49.453 -        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'):
  49.454 -            err("Argument type not supported.")
  49.455 -        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
  49.456 -        arg2 = ['ssidref', str(ssidref)]
  49.457 -
  49.458 -    # accept only int or string types for domid and ssidref
  49.459 -    if isinstance(arg1[1], int):
  49.460 -        arg1[1] = str(arg1[1])
  49.461 -    if isinstance(arg2[1], int):
  49.462 -        arg2[1] = str(arg2[1])
  49.463 -    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
  49.464 -        err("Invalid id or ssidref type, string or int required")
  49.465 -
  49.466 -    try:
  49.467 -        decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1],
  49.468 -                                   ACMHOOK_sharing)
  49.469 -    except:
  49.470 -        err("Cannot determine decision.")
  49.471 -
  49.472 -    if decision:
  49.473 -        return decision
  49.474 -    else:
  49.475 -        err("Cannot determine decision (Invalid parameter).")
  49.476 -
  49.477 -
  49.478 -def has_authorization(ssidref):
  49.479 -    """ Check if the domain with the given ssidref has authorization to
  49.480 -        run on this system. To have authoriztion dom0's STE types must
  49.481 -        be a superset of that of the domain's given through its ssidref.
  49.482 -    """
  49.483 -    rc = True
  49.484 -    dom0_ssidref = int(acm.getssid(0)['ssidref'])
  49.485 -    decision = acm.getdecision('ssidref', str(dom0_ssidref),
  49.486 -                               'ssidref', str(ssidref),
  49.487 -                               ACMHOOK_authorization)
  49.488 -    if decision == "DENIED":
  49.489 -        rc = False
  49.490 -    return rc
  49.491 -
  49.492 -
  49.493 -def hv_chg_policy(bin_pol, del_array, chg_array):
  49.494 -    """
  49.495 -        Change the binary policy in the hypervisor
  49.496 -        The 'del_array' and 'chg_array' give hints about deleted ssidrefs
  49.497 -        and changed ssidrefs which can be due to deleted VM labels
  49.498 -        or reordered VM labels
  49.499 -    """
  49.500 -    rc = -xsconstants.XSERR_GENERAL_FAILURE
  49.501 -    errors = ""
  49.502 -    if not on():
  49.503 -        err("No policy active.")
  49.504 -    try:
  49.505 -        rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
  49.506 -    except Exception, e:
  49.507 -        pass
  49.508 -    if len(errors) > 0:
  49.509 -        rc = -xsconstants.XSERR_HV_OP_FAILED
  49.510 -    return rc, errors
  49.511 -
  49.512 -
  49.513 -def make_policy(policy_name):
  49.514 -    policy_file = string.join(string.split(policy_name, "."), "/")
  49.515 -    if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"):
  49.516 -        err("Unknown policy \'" + policy_name + "\'")
  49.517 -
  49.518 -    (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file)
  49.519 -    if ret:
  49.520 -        err("Creating policy failed:\n" + output)
  49.521 -
  49.522 -def load_policy(policy_name):
  49.523 -    global active_policy
  49.524 -    policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/")
  49.525 -    if not os.path.isfile(policy_file + ".bin"):
  49.526 -        if os.path.isfile(policy_file + "-security_policy.xml"):
  49.527 -            err("Binary file does not exist." +
  49.528 -                "Please use makepolicy to build the policy binary.")
  49.529 -        else:
  49.530 -            err("Unknown Policy " + policy_name)
  49.531 -
  49.532 -    #require this policy to be the first or the same as installed
  49.533 -    if active_policy not in ['DEFAULT', policy_name]:
  49.534 -        err("Active policy \'" + active_policy +
  49.535 -            "\' incompatible with new policy \'" + policy_name + "\'")
  49.536 -    (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin")
  49.537 -    if ret:
  49.538 -        err("Loading policy failed:\n" + output)
  49.539 -    else:
  49.540 -        # refresh active policy
  49.541 -        refresh_security_policy()
  49.542 -
  49.543 -
  49.544 -
  49.545 -def dump_policy():
  49.546 -    if active_policy in ['NULL', 'INACTIVE']:
  49.547 -        err("\'" + active_policy + "\' policy. Nothing to dump.")
  49.548 -
  49.549 -    (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
  49.550 -    if ret:
  49.551 -       err("Dumping hypervisor policy failed:\n" + output)
  49.552 -    print output
  49.553 -
  49.554 -
  49.555 -
  49.556 -def list_labels(policy_name, condition):
  49.557 -    if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]:
  49.558 -        err("Current policy \'" + active_policy + "\' has no labels defined.\n")
  49.559 -
  49.560 -    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
  49.561 -    if not f:
  49.562 -        if pol_exists:
  49.563 -            err("Cannot find mapfile for policy \'" + policy_name +
  49.564 -                "\'.\nPlease use makepolicy to create mapping file.")
  49.565 -        else:
  49.566 -            err("Unknown policy \'" + policy_name + "\'")
  49.567 -
  49.568 -    labels = []
  49.569 -    for line in f:
  49.570 -        if condition.match(line):
  49.571 -            label = line.split()[3]
  49.572 -            if label not in labels:
  49.573 -                labels.append(label)
  49.574 -    return labels
  49.575 -
  49.576 -
  49.577 -def get_res_label(resource):
  49.578 -    """Returns resource label information (policytype, label, policy) if
  49.579 -       it exists. Otherwise returns null label and policy.
  49.580 -    """
  49.581 -    def default_res_label():
  49.582 -        ssidref = NULL_SSIDREF
  49.583 -        if on():
  49.584 -            label = ssidref2label(ssidref)
  49.585 -        else:
  49.586 -            label = None
  49.587 -        return (xsconstants.ACM_POLICY_ID, 'NULL', label)
  49.588 -
  49.589 -
  49.590 -    tmp = get_resource_label(resource)
  49.591 -    if len(tmp) == 2:
  49.592 -        policytype = xsconstants.ACM_POLICY_ID
  49.593 -        policy, label = tmp
  49.594 -    elif len(tmp) == 3:
  49.595 -        policytype, policy, label = tmp
  49.596 -    else:
  49.597 -        policytype, policy, label = default_res_label()
  49.598 -
  49.599 -    return (policytype, label, policy)
  49.600 -
  49.601 -
  49.602 -def get_res_security_details(resource):
  49.603 -    """Returns the (label, ssidref, policy) associated with a given
  49.604 -       resource from the global resource label file.
  49.605 -    """
  49.606 -    def default_security_details():
  49.607 -        ssidref = NULL_SSIDREF
  49.608 -        if on():
  49.609 -            label = ssidref2label(ssidref)
  49.610 -        else:
  49.611 -            label = None
  49.612 -        policy = active_policy
  49.613 -        return (label, ssidref, policy)
  49.614 -
  49.615 -    (label, ssidref, policy) = default_security_details()
  49.616 -
  49.617 -    # find the entry associated with this resource
  49.618 -    (policytype, label, policy) = get_res_label(resource)
  49.619 -    if policy == 'NULL':
  49.620 -        log.info("Resource label for "+resource+" not in file, using DEFAULT.")
  49.621 -        return default_security_details()
  49.622 -
  49.623 -    # is this resource label for the running policy?
  49.624 -    if policy == active_policy:
  49.625 -        ssidref = label2ssidref(label, policy, 'res')
  49.626 -    else:
  49.627 -        log.info("Resource label not for active policy, using DEFAULT.")
  49.628 -        return default_security_details()
  49.629 -
  49.630 -    return (label, ssidref, policy)
  49.631 -
  49.632 -def security_label_to_details(seclab):
  49.633 -    """ Convert a Xen-API type of security label into details """
  49.634 -    def default_security_details():
  49.635 -        ssidref = NULL_SSIDREF
  49.636 -        if on():
  49.637 -            label = ssidref2label(ssidref)
  49.638 -        else:
  49.639 -            label = None
  49.640 -        policy = active_policy
  49.641 -        return (label, ssidref, policy)
  49.642 -
  49.643 -    (policytype, policy, label) = seclab.split(":")
  49.644 -
  49.645 -    # is this resource label for the running policy?
  49.646 -    if policy == active_policy:
  49.647 -        ssidref = label2ssidref(label, policy, 'res')
  49.648 -    else:
  49.649 -        log.info("Resource label not for active policy, using DEFAULT.")
  49.650 -        return default_security_details()
  49.651 -
  49.652 -    return (label, ssidref, policy)
  49.653 -
  49.654 -def unify_resname(resource, mustexist=True):
  49.655 -    """Makes all resource locations absolute. In case of physical
  49.656 -    resources, '/dev/' is added to local file names"""
  49.657 -
  49.658 -    if not resource:
  49.659 -        return resource
  49.660 -
  49.661 -    # sanity check on resource name
  49.662 -    try:
  49.663 -        (typ, resfile) = resource.split(":", 1)
  49.664 -    except:
  49.665 -        err("Resource spec '%s' contains no ':' delimiter" % resource)
  49.666 -
  49.667 -    if typ == "tap":
  49.668 -        try:
  49.669 -            (subtype, resfile) = resfile.split(":")
  49.670 -        except:
  49.671 -            err("Resource spec '%s' contains no tap subtype" % resource)
  49.672 -
  49.673 -    import os
  49.674 -    if typ in ["phy", "tap"]:
  49.675 -        if not resfile.startswith("/"):
  49.676 -            resfile = "/dev/" + resfile
  49.677 -        if mustexist:
  49.678 -            stats = os.lstat(resfile)
  49.679 -            if stat.S_ISLNK(stats[stat.ST_MODE]):
  49.680 -                resolved = os.readlink(resfile)
  49.681 -                if resolved[0] != "/":
  49.682 -                    resfile = os.path.join(os.path.dirname(resfile), resolved)
  49.683 -                    resfile = os.path.abspath(resfile)
  49.684 -                else:
  49.685 -                    resfile = resolved
  49.686 -                stats = os.lstat(resfile)
  49.687 -            if not (stat.S_ISBLK(stats[stat.ST_MODE])):
  49.688 -                err("Invalid resource")
  49.689 -
  49.690 -    if typ in [ "file", "tap" ]:
  49.691 -        if mustexist:
  49.692 -            stats = os.lstat(resfile)
  49.693 -            if stat.S_ISLNK(stats[stat.ST_MODE]):
  49.694 -                resfile = os.readlink(resfile)
  49.695 -                stats = os.lstat(resfile)
  49.696 -            if not stat.S_ISREG(stats[stat.ST_MODE]):
  49.697 -                err("Invalid resource")
  49.698 -
  49.699 -    #file: resources must specified with absolute path
  49.700 -    #vlan resources don't start with '/'
  49.701 -    if typ != "vlan":
  49.702 -        if (not resfile.startswith("/")) or \
  49.703 -           (mustexist and not os.path.exists(resfile)):
  49.704 -            err("Invalid resource.")
  49.705 -
  49.706 -    # from here on absolute file names with resources
  49.707 -    if typ == "tap":
  49.708 -        typ = typ + ":" + subtype
  49.709 -    resource = typ + ":" + resfile
  49.710 -    return resource
  49.711 -
  49.712 -
  49.713 -def res_security_check(resource, domain_label):
  49.714 -    """Checks if the given resource can be used by the given domain
  49.715 -       label.  Returns 1 if the resource can be used, otherwise 0.
  49.716 -    """
  49.717 -    rtnval = 1
  49.718 -
  49.719 -    # if security is on, ask the hypervisor for a decision
  49.720 -    if on():
  49.721 -        #build canonical resource name
  49.722 -        resource = unify_resname(resource)
  49.723 -
  49.724 -        (label, ssidref, policy) = get_res_security_details(resource)
  49.725 -        domac = ['access_control']
  49.726 -        domac.append(['policy', active_policy])
  49.727 -        domac.append(['label', domain_label])
  49.728 -        domac.append(['type', 'dom'])
  49.729 -        decision = get_decision(domac, ['ssidref', str(ssidref)])
  49.730 -
  49.731 -        # provide descriptive error messages
  49.732 -        if decision == 'DENIED':
  49.733 -            if label == ssidref2label(NULL_SSIDREF):
  49.734 -                raise ACMError("Resource '"+resource+"' is not labeled")
  49.735 -                rtnval = 0
  49.736 -            else:
  49.737 -                raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed")
  49.738 -                rtnval = 0
  49.739 -
  49.740 -    # security is off, make sure resource isn't labeled
  49.741 -    else:
  49.742 -        # Note, we can't canonicalise the resource here, because people using
  49.743 -        # xm without ACM are free to use relative paths.
  49.744 -        (policytype, label, policy) = get_res_label(resource)
  49.745 -        if policy != 'NULL':
  49.746 -            raise ACMError("Security is off, but '"+resource+"' is labeled")
  49.747 -            rtnval = 0
  49.748 -
  49.749 -    return rtnval
  49.750 -
  49.751 -def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
  49.752 -    """Checks if the given resource can be used by the given domain
  49.753 -       label.  Returns 1 if the resource can be used, otherwise 0.
  49.754 -    """
  49.755 -    rtnval = 1
  49.756 -    # if security is on, ask the hypervisor for a decision
  49.757 -    if on():
  49.758 -        typ, dpolicy, domain_label = xapi_dom_label.split(":")
  49.759 -        if not dpolicy or not domain_label:
  49.760 -            raise VmError("VM security label in wrong format.")
  49.761 -        if active_policy != rpolicy:
  49.762 -            raise VmError("Resource's policy '%s' != active policy '%s'" %
  49.763 -                          (rpolicy, active_policy))
  49.764 -        domac = ['access_control']
  49.765 -        domac.append(['policy', active_policy])
  49.766 -        domac.append(['label', domain_label])
  49.767 -        domac.append(['type', 'dom'])
  49.768 -        decision = get_decision(domac, ['ssidref', str(rssidref)])
  49.769 -
  49.770 -        log.info("Access Control Decision : %s" % decision)
  49.771 -        # provide descriptive error messages
  49.772 -        if decision == 'DENIED':
  49.773 -            if rlabel == ssidref2label(NULL_SSIDREF):
  49.774 -                #raise ACMError("Resource is not labeled")
  49.775 -                rtnval = 0
  49.776 -            else:
  49.777 -                #raise ACMError("Permission denied for resource because label '"+rlabel+"' is not allowed")
  49.778 -                rtnval = 0
  49.779 -
  49.780 -    # security is off, make sure resource isn't labeled
  49.781 -    else:
  49.782 -        # Note, we can't canonicalise the resource here, because people using
  49.783 -        # xm without ACM are free to use relative paths.
  49.784 -        if rpolicy != 'NULL':
  49.785 -            #raise ACMError("Security is off, but resource is labeled")
  49.786 -            rtnval = 0
  49.787 -
  49.788 -    return rtnval
  49.789 -
  49.790 -
  49.791 -def validate_label(label, policyref):
  49.792 -    """
  49.793 -       Make sure that this label is part of the currently enforced policy
  49.794 -       and that it reference the current policy.
  49.795 -    """
  49.796 -    rc = xsconstants.XSERR_SUCCESS
  49.797 -    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  49.798 -    curpol = XSPolicyAdminInstance().get_loaded_policy()
  49.799 -    if not curpol or curpol.get_name() != policyref:
  49.800 -        rc = -xsconstants.XSERR_BAD_LABEL
  49.801 -    else:
  49.802 -        try:
  49.803 -            label2ssidref(label, curpol.get_name() , 'res')
  49.804 -        except:
  49.805 -            rc = -xsconstants.XSERR_BAD_LABEL
  49.806 -    return rc
  49.807 -
  49.808 -
  49.809 -def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
  49.810 -    """Assign a resource label to a resource
  49.811 -    @param resource: The name of a resource, i.e., "phy:/dev/hda", or
  49.812 -              "tap:qcow:/path/to/file.qcow"
  49.813 -
  49.814 -    @param reslabel_xapi: A resource label foramtted as in all other parts of
  49.815 -                          the Xen-API, i.e., ACM:xm-test:blue"
  49.816 -    @rtype: int
  49.817 -    @return Success (0) or failure value (< 0)
  49.818 -    """
  49.819 -    olabel = ""
  49.820 -    if reslabel_xapi == "":
  49.821 -        return rm_resource_label(resource, oldlabel_xapi)
  49.822 -    typ, policyref, label = reslabel_xapi.split(":")
  49.823 -    if typ != xsconstants.ACM_POLICY_ID:
  49.824 -        return -xsconstants.XSERR_WRONG_POLICY_TYPE
  49.825 -    if not policyref or not label:
  49.826 -        return -xsconstants.XSERR_BAD_LABEL_FORMAT
  49.827 -    if oldlabel_xapi not in [ "" ]:
  49.828 -        tmp = oldlabel_xapi.split(":")
  49.829 -        if len(tmp) != 3:
  49.830 -            return -xsconstants.XSERR_BAD_LABEL_FORMAT
  49.831 -        otyp, opolicyref, olabel = tmp
  49.832 -        # Only ACM is supported
  49.833 -        if otyp != xsconstants.ACM_POLICY_ID  and \
  49.834 -           otyp != xsconstants.INVALID_POLICY_PREFIX + \
  49.835 -                   xsconstants.ACM_POLICY_ID:
  49.836 -            return -xsconstants.XSERR_WRONG_POLICY_TYPE
  49.837 -    rc = validate_label(label, policyref)
  49.838 -    if rc != xsconstants.XSERR_SUCCESS:
  49.839 -        return rc
  49.840 -    return set_resource_label(resource, typ, policyref, label, olabel)
  49.841 -
  49.842 -
  49.843 -def is_resource_in_use(resource):
  49.844 -    """
  49.845 -       Domain-0 'owns' resources of type 'VLAN', the rest are owned by
  49.846 -       the guests.
  49.847 -    """
  49.848 -    from xen.xend import XendDomain
  49.849 -    lst = []
  49.850 -    if resource.startswith('vlan'):
  49.851 -        from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  49.852 -        curpol = XSPolicyAdminInstance().get_loaded_policy()
  49.853 -        policytype, label, policy = get_res_label(resource)
  49.854 -        if curpol and \
  49.855 -           policytype == xsconstants.ACM_POLICY_ID and \
  49.856 -           policy == curpol.get_name() and \
  49.857 -           label in curpol.policy_get_resourcelabel_names():
  49.858 -            # VLAN is in use.
  49.859 -            lst.append(XendDomain.instance().
  49.860 -                         get_vm_by_uuid(XendDomain.DOM0_UUID))
  49.861 -    else:
  49.862 -        dominfos = XendDomain.instance().list('all')
  49.863 -        for dominfo in dominfos:
  49.864 -            if is_resource_in_use_by_dom(dominfo, resource):
  49.865 -                lst.append(dominfo)
  49.866 -    return lst
  49.867 -
  49.868 -def devices_equal(res1, res2, mustexist=True):
  49.869 -    """ Determine whether two devices are equal """
  49.870 -    return (unify_resname(res1, mustexist) ==
  49.871 -            unify_resname(res2, mustexist))
  49.872 -
  49.873 -def is_resource_in_use_by_dom(dominfo, resource):
  49.874 -    """ Determine whether a resources is in use by a given domain
  49.875 -        @return True or False
  49.876 -    """
  49.877 -    if not dominfo.domid:
  49.878 -        return False
  49.879 -    if dominfo._stateGet() not in [ DOM_STATE_RUNNING ]:
  49.880 -        return False
  49.881 -    devs = dominfo.info['devices']
  49.882 -    uuids = devs.keys()
  49.883 -    for uuid in uuids:
  49.884 -        dev = devs[uuid]
  49.885 -        if len(dev) >= 2 and dev[1].has_key('uname'):
  49.886 -            # dev[0] is type, i.e. 'vbd'
  49.887 -            if devices_equal(dev[1]['uname'], resource, mustexist=False):
  49.888 -                log.info("RESOURCE IN USE: Domain %d uses %s." %
  49.889 -                         (dominfo.domid, resource))
  49.890 -                return True
  49.891 -    return False
  49.892 -
  49.893 -
  49.894 -def get_domain_resources(dominfo):
  49.895 -    """ Collect all resources of a domain in a map where each entry of
  49.896 -        the map is a list.
  49.897 -        Entries are strored in the following formats:
  49.898 -          tap:qcow:/path/xyz.qcow
  49.899 -    """
  49.900 -    resources = { 'vbd' : [], 'tap' : [], 'vif' : []}
  49.901 -    devs = dominfo.info['devices']
  49.902 -    uuids = devs.keys()
  49.903 -    for uuid in uuids:
  49.904 -        dev = devs[uuid]
  49.905 -        typ = dev[0]
  49.906 -        if typ in [ 'vbd', 'tap' ]:
  49.907 -            resources[typ].append(dev[1]['uname'])
  49.908 -        if typ in [ 'vif' ]:
  49.909 -            sec_lab = dev[1].get('security_label')
  49.910 -            if sec_lab:
  49.911 -                resources[typ].append(sec_lab)
  49.912 -            else:
  49.913 -                # !!! This should really get the label of the domain
  49.914 -                # or at least a resource label that has the same STE type
  49.915 -                # as the domain has
  49.916 -                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  49.917 -                resources[typ].append("%s:%s:%s" %
  49.918 -                                      (xsconstants.ACM_POLICY_ID,
  49.919 -                                       active_policy,
  49.920 -                                       ACM_LABEL_UNLABELED))
  49.921 -
  49.922 -    return resources
  49.923 -
  49.924 -
  49.925 -def resources_compatible_with_vmlabel(xspol, dominfo, vmlabel):
  49.926 -    """
  49.927 -       Check whether the resources' labels are compatible with the
  49.928 -       given VM label. This is a function to be used when for example
  49.929 -       a running domain is to get the new label 'vmlabel'
  49.930 -    """
  49.931 -    if not xspol:
  49.932 -        return False
  49.933 -
  49.934 -    try:
  49.935 -        __resfile_lock.acquire()
  49.936 -        try:
  49.937 -            access_control = dictio.dict_read("resources",
  49.938 -                                              res_label_filename)
  49.939 -        except:
  49.940 -            return False
  49.941 -        return __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  49.942 -                                                   access_control)
  49.943 -    finally:
  49.944 -        __resfile_lock.release()
  49.945 -    return False
  49.946 -
  49.947 -
  49.948 -def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  49.949 -                                        access_control,
  49.950 -                                        is_policy_update=False):
  49.951 -    """
  49.952 -        Check whether the resources' labels are compatible with the
  49.953 -        given VM label. The access_control parameter provides a
  49.954 -        dictionary of the resource name to resource label mappings
  49.955 -        under which the evaluation should be done.
  49.956 -    """
  49.957 -    def collect_labels(reslabels, s_label, polname):
  49.958 -        if len(s_label) != 3 or polname != s_label[1]:
  49.959 -            return False
  49.960 -        label = s_label[2]
  49.961 -        if not label in reslabels:
  49.962 -            reslabels.append(label)
  49.963 -        return True
  49.964 -
  49.965 -    resources = get_domain_resources(dominfo)
  49.966 -    reslabels = []  # all resource labels
  49.967 -
  49.968 -    polname = xspol.get_name()
  49.969 -    for key, value in resources.items():
  49.970 -        if key in [ 'vbd', 'tap' ]:
  49.971 -            for res in resources[key]:
  49.972 -                try:
  49.973 -                    label = access_control[res]
  49.974 -                    if not collect_labels(reslabels, label, polname):
  49.975 -                        return False
  49.976 -                except:
  49.977 -                    return False
  49.978 -        elif key in [ 'vif' ]:
  49.979 -            for xapi_label in value:
  49.980 -                label = xapi_label.split(":")
  49.981 -                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  49.982 -                if not (is_policy_update and \
  49.983 -                        label[2] == ACM_LABEL_UNLABELED):
  49.984 -                    if not collect_labels(reslabels, label, polname):
  49.985 -                        return False
  49.986 -        else:
  49.987 -            log.error("Unhandled device type: %s" % key)
  49.988 -            return False
  49.989 -
  49.990 -    # Check that all resource labes have a common STE type with the
  49.991 -    # vmlabel
  49.992 -    if len(reslabels) > 0:
  49.993 -        rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
  49.994 -    else:
  49.995 -        rc = True
  49.996 -    log.info("vmlabel=%s, reslabels=%s, rc=%s" %
  49.997 -             (vmlabel, reslabels, str(rc)))
  49.998 -    return rc;
  49.999 -
 49.1000 -def set_resource_label(resource, policytype, policyref, reslabel, \
 49.1001 -                       oreslabel = None):
 49.1002 -    """Assign a label to a resource
 49.1003 -       If the old label (oreslabel) is given, then the resource must have
 49.1004 -       that old label.
 49.1005 -       A resource label may be changed if
 49.1006 -       - the resource is not in use
 49.1007 -    @param resource  : The name of a resource, i.e., "phy:/dev/hda"
 49.1008 -    @param policyref : The name of the policy
 49.1009 -    @param reslabel     : the resource label within the policy
 49.1010 -    @param oreslabel    : optional current resource label
 49.1011 -
 49.1012 -    @rtype: int
 49.1013 -    @return Success (0) or failure value (< 0)
 49.1014 -    """
 49.1015 -    try:
 49.1016 -        resource = unify_resname(resource, mustexist=False)
 49.1017 -    except Exception:
 49.1018 -        return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
 49.1019 -
 49.1020 -    domains = is_resource_in_use(resource)
 49.1021 -    if len(domains) > 0:
 49.1022 -        return -xsconstants.XSERR_RESOURCE_IN_USE
 49.1023 -
 49.1024 -    try:
 49.1025 -        __resfile_lock.acquire()
 49.1026 -        access_control = {}
 49.1027 -        try:
 49.1028 -             access_control = dictio.dict_read("resources", res_label_filename)
 49.1029 -        except:
 49.1030 -            pass
 49.1031 -        if oreslabel:
 49.1032 -            if not access_control.has_key(resource):
 49.1033 -                return -xsconstants.XSERR_BAD_LABEL
 49.1034 -            tmp = access_control[resource]
 49.1035 -            if len(tmp) != 3:
 49.1036 -                return -xsconstants.XSERR_BAD_LABEL
 49.1037 -            if tmp[2] != oreslabel:
 49.1038 -                return -xsconstants.XSERR_BAD_LABEL
 49.1039 -        if reslabel != "":
 49.1040 -            new_entry = { resource : tuple([policytype, policyref, reslabel])}
 49.1041 -            access_control.update(new_entry)
 49.1042 -        else:
 49.1043 -            if access_control.has_key(resource):
 49.1044 -                del access_control[resource]
 49.1045 -        dictio.dict_write(access_control, "resources", res_label_filename)
 49.1046 -    finally:
 49.1047 -        __resfile_lock.release()
 49.1048 -    return xsconstants.XSERR_SUCCESS
 49.1049 -
 49.1050 -def rm_resource_label(resource, oldlabel_xapi):
 49.1051 -    """Remove a resource label from a physical resource
 49.1052 -    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 49.1053 -
 49.1054 -    @rtype: int
 49.1055 -    @return Success (0) or failure value (< 0)
 49.1056 -    """
 49.1057 -    tmp = oldlabel_xapi.split(":")
 49.1058 -    if len(tmp) != 3:
 49.1059 -        return -xsconstants.XSERR_BAD_LABEL_FORMAT
 49.1060 -    otyp, opolicyref, olabel = tmp
 49.1061 -    # Only ACM is supported
 49.1062 -    if otyp != xsconstants.ACM_POLICY_ID and \
 49.1063 -       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:
 49.1064 -        return -xsconstants.XSERR_WRONG_POLICY_TYPE
 49.1065 -    return set_resource_label(resource, "", "", "", olabel)
 49.1066 -
 49.1067 -def get_resource_label_xapi(resource):
 49.1068 -    """Get the assigned resource label of a physical resource
 49.1069 -      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"
 49.1070 -
 49.1071 -      @rtype: string
 49.1072 -      @return the string representing policy type, policy name and label of
 49.1073 -              the resource
 49.1074 -    """
 49.1075 -    res = get_resource_label(resource)
 49.1076 -    return format_resource_label(res)
 49.1077 -
 49.1078 -def format_resource_label(res):
 49.1079 -    if res:
 49.1080 -        if len(res) == 2:
 49.1081 -            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]
 49.1082 -        if len(res) == 3:
 49.1083 -            return ":".join(res)
 49.1084 -    return ""
 49.1085 -
 49.1086 -def get_resource_label(resource):
 49.1087 -    """Get the assigned resource label of a given resource
 49.1088 -    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 49.1089 -
 49.1090 -    @rtype: list
 49.1091 -    @return tuple of (policy name, resource label), i.e., (xm-test, blue)
 49.1092 -    """
 49.1093 -    try:
 49.1094 -        resource = unify_resname(resource, mustexist=False)
 49.1095 -    except Exception:
 49.1096 -        return []
 49.1097 -
 49.1098 -    reslabel_map = get_labeled_resources()
 49.1099 -
 49.1100 -    if reslabel_map.has_key(resource):
 49.1101 -        return list(reslabel_map[resource])
 49.1102 -    else:
 49.1103 -        #Try to resolve each label entry
 49.1104 -        for key, value in reslabel_map.items():
 49.1105 -            try:
 49.1106 -                if resource == unify_resname(key):
 49.1107 -                    return list(value)
 49.1108 -            except:
 49.1109 -                pass
 49.1110 -
 49.1111 -    return []
 49.1112 -
 49.1113 -
 49.1114 -def get_labeled_resources_xapi():
 49.1115 -    """ Get a map of all labeled resource with the labels formatted in the
 49.1116 -        xen-api resource label format.
 49.1117 -    """
 49.1118 -    reslabel_map = get_labeled_resources()
 49.1119 -    for key, labeldata in reslabel_map.items():
 49.1120 -        reslabel_map[key] = format_resource_label(labeldata)
 49.1121 -    return reslabel_map
 49.1122 -
 49.1123 -
 49.1124 -def get_labeled_resources():
 49.1125 -    """Get a map of all labeled resources
 49.1126 -    @rtype: list
 49.1127 -    @return list of labeled resources
 49.1128 -    """
 49.1129 -    try:
 49.1130 -        __resfile_lock.acquire()
 49.1131 -        try:
 49.1132 -            access_control = dictio.dict_read("resources", res_label_filename)
 49.1133 -        except:
 49.1134 -            return {}
 49.1135 -    finally:
 49.1136 -        __resfile_lock.release()
 49.1137 -    return access_control
 49.1138 -
 49.1139 -
 49.1140 -def relabel_domains(relabel_list):
 49.1141 -    """
 49.1142 -      Relabel the given domains to have a new ssidref.
 49.1143 -      @param relabel_list: a list containing tuples of domid, ssidref
 49.1144 -                           example: [ [0, 0x00020002] ]
 49.1145 -    """
 49.1146 -    rel_rules = ""
 49.1147 -    for r in relabel_list:
 49.1148 -        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",
 49.1149 -                r[0], r[1])
 49.1150 -        rel_rules += struct.pack("ii", r[0], r[1])
 49.1151 -    try:
 49.1152 -        rc, errors = acm.relabel_domains(rel_rules)
 49.1153 -    except Exception, e:
 49.1154 -        log.info("Error after relabel_domains: %s" % str(e))
 49.1155 -        rc = -xsconstants.XSERR_GENERAL_FAILURE
 49.1156 -        errors = ""
 49.1157 -    if (len(errors) > 0):
 49.1158 -        rc = -xsconstants.XSERR_HV_OP_FAILED
 49.1159 -    return rc, errors
 49.1160 -
 49.1161 -
 49.1162 -def change_acm_policy(bin_pol, del_array, chg_array,
 49.1163 -                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):
 49.1164 -    """
 49.1165 -       Change the ACM policy of the system by relabeling
 49.1166 -       domains and resources first and doing some access checks.
 49.1167 -       Then update the policy in the hypervisor. If this is all successful,
 49.1168 -       relabel the domains permanently and commit the relabed resources.
 49.1169 -
 49.1170 -       Need to do / check the following:
 49.1171 -        - relabel all resources where there is a 'from' field in
 49.1172 -          the policy. [ NOT DOING THIS: and mark those as unlabeled where the label
 49.1173 -          does not appear in the new policy anymore (deletion) ]
 49.1174 -        - relabel all VMs where there is a 'from' field in the
 49.1175 -          policy and mark those as unlabeled where the label
 49.1176 -          does not appear in the new policy anymore; no running
 49.1177 -          or paused VM may be unlabeled through this
 49.1178 -        - check that under the new labeling conditions the VMs
 49.1179 -          still have access to their resources as before. Unlabeled
 49.1180 -          resources are inaccessible. If this check fails, the
 49.1181 -          update failed.
 49.1182 -        - Attempt changes in the hypervisor; if this step fails,
 49.1183 -          roll back the relabeling of resources and VMs
 49.1184 -        - Make the relabeling of resources and VMs permanent
 49.1185 -    """
 49.1186 -    rc = xsconstants.XSERR_SUCCESS
 49.1187 -
 49.1188 -    domain_label_map = {}
 49.1189 -    new_policyname = new_acmpol.get_name()
 49.1190 -    new_policytype = new_acmpol.get_type_name()
 49.1191 -    cur_policyname = cur_acmpol.get_name()
 49.1192 -    cur_policytype = cur_acmpol.get_type_name()
 49.1193 -    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()
 49.1194 -    errors=""
 49.1195 -
 49.1196 -    try:
 49.1197 -        __resfile_lock.acquire()
 49.1198 -        mapfile_lock()
 49.1199 -
 49.1200 -        # Get all domains' dominfo.
 49.1201 -        from xen.xend import XendDomain
 49.1202 -        dominfos = XendDomain.instance().list('all')
 49.1203 -
 49.1204 -        log.info("----------------------------------------------")
 49.1205 -        # relabel resources
 49.1206 -
 49.1207 -        access_control = {}
 49.1208 -        try:
 49.1209 -            access_control = dictio.dict_read("resources", res_label_filename)
 49.1210 -        finally:
 49.1211 -            pass
 49.1212 -        for key, labeldata in access_control.items():
 49.1213 -            if len(labeldata) == 2:
 49.1214 -                policy, label = labeldata
 49.1215 -                policytype = xsconstants.ACM_POLICY_ID
 49.1216 -            elif len(labeldata) == 3:
 49.1217 -                policytype, policy, label = labeldata
 49.1218 -            else:
 49.1219 -                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""
 49.1220 -
 49.1221 -            if policytype != cur_policytype or \
 49.1222 -               policy     != cur_policyname:
 49.1223 -                continue
 49.1224 -
 49.1225 -            # label been renamed or deleted?
 49.1226 -            if reslabel_map.has_key(label) and cur_policyname == policy:
 49.1227 -                label = reslabel_map[label]
 49.1228 -            elif label not in polnew_reslabels:
 49.1229 -                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 49.1230 -            # Update entry
 49.1231 -            access_control[key] = \
 49.1232 -                   tuple([ policytype, new_policyname, label ])
 49.1233 -
 49.1234 -        # All resources have new labels in the access_control map
 49.1235 -        # There may still be labels in there that are invalid now.
 49.1236 -
 49.1237 -        # Do this in memory without writing to disk:
 49.1238 -        #  - Relabel all domains independent of whether they are running
 49.1239 -        #    or not
 49.1240 -        #  - later write back to config files
 49.1241 -        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()
 49.1242 -
 49.1243 -        for dominfo in dominfos:
 49.1244 -            sec_lab = dominfo.get_security_label()
 49.1245 -            if not sec_lab:
 49.1246 -                continue
 49.1247 -            policytype, policy, vmlabel = sec_lab.split(":")
 49.1248 -            name  = dominfo.getName()
 49.1249 -
 49.1250 -            if policytype != cur_policytype or \
 49.1251 -               policy     != cur_policyname:
 49.1252 -                continue
 49.1253 -
 49.1254 -            new_vmlabel = vmlabel
 49.1255 -            if vmlabel_map.has_key(vmlabel):
 49.1256 -                new_vmlabel = vmlabel_map[vmlabel]
 49.1257 -            if new_vmlabel not in polnew_vmlabels:
 49.1258 -                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 49.1259 -            new_seclab = "%s:%s:%s" % \
 49.1260 -                    (policytype, new_policyname, new_vmlabel)
 49.1261 -
 49.1262 -            domain_label_map[dominfo] = [ sec_lab, new_seclab ]
 49.1263 -
 49.1264 -            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
 49.1265 -                compatible = __resources_compatible_with_vmlabel(new_acmpol,
 49.1266 -                                                      dominfo,
 49.1267 -                                                      new_vmlabel,
 49.1268 -                                                      access_control,
 49.1269 -                                                      is_policy_update=True)
 49.1270 -                log.info("Domain %s with new label '%s' can access its "
 49.1271 -                         "resources? : %s" %
 49.1272 -                         (name, new_vmlabel, str(compatible)))
 49.1273 -                log.info("VM labels in new policy: %s" %
 49.1274 -                         new_acmpol.policy_get_virtualmachinelabel_names())
 49.1275 -                if not compatible:
 49.1276 -                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
 49.1277 -
 49.1278 -        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)
 49.1279 -        if rc == 0:
 49.1280 -            # Write the relabeled resources back into the file
 49.1281 -            dictio.dict_write(access_control, "resources", res_label_filename)
 49.1282 -            # Properly update all VMs to their new labels
 49.1283 -            for dominfo, labels in domain_label_map.items():
 49.1284 -                sec_lab, new_seclab = labels
 49.1285 -                if sec_lab != new_seclab:
 49.1286 -                    log.info("Updating domain %s to new label '%s'." % \
 49.1287 -                             (dominfo.getName(), new_seclab))
 49.1288 -                    # This better be working!
 49.1289 -                    res = dominfo.set_security_label(new_seclab,
 49.1290 -                                                     sec_lab,
 49.1291 -                                                     new_acmpol,
 49.1292 -                                                     cur_acmpol)
 49.1293 -                    if res[0] != xsconstants.XSERR_SUCCESS:
 49.1294 -                        log.info("ERROR: Could not chg label on domain %s: %s" %
 49.1295 -                                 (dominfo.getName(),
 49.1296 -                                  xsconstants.xserr2string(-int(res[0]))))
 49.1297 -    finally:
 49.1298 -        log.info("----------------------------------------------")
 49.1299 -        mapfile_unlock()
 49.1300 -        __resfile_lock.release()
 49.1301 -
 49.1302 -    return rc, errors
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tools/python/xen/util/xsm/__init__.py	Thu Sep 06 12:05:15 2007 -0600
    50.3 @@ -0,0 +1,2 @@
    50.4 +
    50.5 +
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tools/python/xen/util/xsm/acm/__init__.py	Thu Sep 06 12:05:15 2007 -0600
    51.3 @@ -0,0 +1,1 @@
    51.4 + 
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/tools/python/xen/util/xsm/acm/acm.py	Thu Sep 06 12:05:15 2007 -0600
    52.3 @@ -0,0 +1,1319 @@
    52.4 +#===========================================================================
    52.5 +# This library is free software; you can redistribute it and/or
    52.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    52.7 +# License as published by the Free Software Foundation.
    52.8 +#
    52.9 +# This library is distributed in the hope that it will be useful,
   52.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   52.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   52.12 +# Lesser General Public License for more details.
   52.13 +#
   52.14 +# You should have received a copy of the GNU Lesser General Public
   52.15 +# License along with this library; if not, write to the Free Software
   52.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   52.17 +#============================================================================
   52.18 +# Copyright (C) 2006 International Business Machines Corp.
   52.19 +# Author: Reiner Sailer
   52.20 +# Author: Bryan D. Payne <bdpayne@us.ibm.com>
   52.21 +# Author: Stefan Berger <stefanb@us.ibm.com>
   52.22 +#============================================================================
   52.23 +
   52.24 +import commands
   52.25 +import logging
   52.26 +import os, string, re
   52.27 +import threading
   52.28 +import struct
   52.29 +import stat
   52.30 +from xen.lowlevel import acm
   52.31 +from xen.xend import sxp
   52.32 +from xen.xend import XendConstants
   52.33 +from xen.xend.XendLogging import log
   52.34 +from xen.xend.XendError import VmError
   52.35 +from xen.util import dictio, xsconstants
   52.36 +from xen.xend.XendConstants import *
   52.37 +
   52.38 +#global directories and tools for security management
   52.39 +policy_dir_prefix = "/etc/xen/acm-security/policies"
   52.40 +res_label_filename = policy_dir_prefix + "/resource_labels"
   52.41 +boot_filename = "/boot/grub/menu.lst"
   52.42 +altboot_filename = "/boot/grub/grub.conf"
   52.43 +xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
   52.44 +xensec_tool = "/usr/sbin/xensec_tool"
   52.45 +
   52.46 +#global patterns for map file
   52.47 +#police_reference_tagname = "POLICYREFERENCENAME"
   52.48 +primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
   52.49 +secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
   52.50 +label_template_re =  re.compile(".*security_label_template.xml", re.IGNORECASE)
   52.51 +mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
   52.52 +policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE)
   52.53 +vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
   52.54 +res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
   52.55 +all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
   52.56 +access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
   52.57 +
   52.58 +#global patterns for boot configuration file
   52.59 +xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
   52.60 +any_title_re = re.compile("\s*title\s", re.IGNORECASE)
   52.61 +xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
   52.62 +kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
   52.63 +any_module_re = re.compile("\s*module\s", re.IGNORECASE)
   52.64 +empty_line_re = re.compile("^\s*$")
   52.65 +binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
   52.66 +policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
   52.67 +
   52.68 +#decision hooks known to the hypervisor
   52.69 +ACMHOOK_sharing = 1
   52.70 +ACMHOOK_authorization = 2
   52.71 +
   52.72 +#other global variables
   52.73 +NULL_SSIDREF = 0
   52.74 +
   52.75 +#general Rlock for map files; only one lock for all mapfiles
   52.76 +__mapfile_lock = threading.RLock()
   52.77 +__resfile_lock = threading.RLock()
   52.78 +
   52.79 +log = logging.getLogger("xend.util.security")
   52.80 +
   52.81 +# Our own exception definition. It is masked (pass) if raised and
   52.82 +# whoever raises this exception must provide error information.
   52.83 +class ACMError(Exception):
   52.84 +    def __init__(self,value):
   52.85 +        self.value = value
   52.86 +    def __str__(self):
   52.87 +        return repr(self.value)
   52.88 +
   52.89 +
   52.90 +
   52.91 +def err(msg):
   52.92 +    """Raise ACM exception.
   52.93 +    """
   52.94 +    raise ACMError(msg)
   52.95 +
   52.96 +
   52.97 +
   52.98 +active_policy = None
   52.99 +
  52.100 +
  52.101 +def mapfile_lock():
  52.102 +    __mapfile_lock.acquire()
  52.103 +
  52.104 +def mapfile_unlock():
  52.105 +    __mapfile_lock.release()
  52.106 +
  52.107 +
  52.108 +def refresh_security_policy():
  52.109 +    """
  52.110 +    retrieves security policy
  52.111 +    """
  52.112 +    global active_policy
  52.113 +
  52.114 +    try:
  52.115 +        active_policy = acm.policy()
  52.116 +    except:
  52.117 +        active_policy = "INACTIVE"
  52.118 +
  52.119 +# now set active_policy
  52.120 +refresh_security_policy()
  52.121 +
  52.122 +def on():
  52.123 +    """
  52.124 +    returns none if security policy is off (not compiled),
  52.125 +    any string otherwise, use it: if not security.on() ...
  52.126 +    """
  52.127 +    refresh_security_policy()
  52.128 +    return (active_policy not in ['INACTIVE', 'NULL'])
  52.129 +
  52.130 +
  52.131 +def calc_dom_ssidref_from_info(info):
  52.132 +    """
  52.133 +       Calculate a domain's ssidref from the security_label in its
  52.134 +       info.
  52.135 +       This function is called before the domain is started and
  52.136 +       makes sure that:
  52.137 +        - the type of the policy is the same as indicated in the label
  52.138 +        - the name of the policy is the same as indicated in the label
  52.139 +        - calculates an up-to-date ssidref for the domain
  52.140 +       The latter is necessary since the domain's ssidref could have
  52.141 +       changed due to changes to the policy.
  52.142 +    """
  52.143 +    import xen.xend.XendConfig
  52.144 +    if isinstance(info, xen.xend.XendConfig.XendConfig):
  52.145 +        if info.has_key('security_label'):
  52.146 +            seclab = info['security_label']
  52.147 +            tmp = seclab.split(":")
  52.148 +            if len(tmp) != 3:
  52.149 +                raise VmError("VM label '%s' in wrong format." % seclab)
  52.150 +            typ, policyname, vmlabel = seclab.split(":")
  52.151 +            if typ != xsconstants.ACM_POLICY_ID:
  52.152 +                raise VmError("Policy type '%s' must be changed." % typ)
  52.153 +            refresh_security_policy()
  52.154 +            if active_policy != policyname:
  52.155 +                raise VmError("Active policy '%s' different than "
  52.156 +                              "what in VM's label ('%s')." %
  52.157 +                              (active_policy, policyname))
  52.158 +            ssidref = label2ssidref(vmlabel, policyname, "dom")
  52.159 +            return ssidref
  52.160 +        else:
  52.161 +            return 0x0
  52.162 +    raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
  52.163 +                  "not supported." % type(info))
  52.164 +
  52.165 +
  52.166 +def getmapfile(policyname):
  52.167 +    """
  52.168 +    in: if policyname is None then the currently
  52.169 +    active hypervisor policy is used
  52.170 +    out: 1. primary policy, 2. secondary policy,
  52.171 +    3. open file descriptor for mapping file, and
  52.172 +    4. True if policy file is available, False otherwise
  52.173 +    """
  52.174 +    if not policyname:
  52.175 +        policyname = active_policy
  52.176 +    map_file_ok = False
  52.177 +    primary = None
  52.178 +    secondary = None
  52.179 +    #strip last part of policy as file name part
  52.180 +    policy_dir_list = string.split(policyname, ".")
  52.181 +    policy_file = policy_dir_list.pop()
  52.182 +    if len(policy_dir_list) > 0:
  52.183 +        policy_dir = string.join(policy_dir_list, "/") + "/"
  52.184 +    else:
  52.185 +        policy_dir = ""
  52.186 +
  52.187 +    map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
  52.188 +    # check if it is there, if not check if policy file is there
  52.189 +    if not os.path.isfile(map_filename):
  52.190 +        policy_filename =  policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml"
  52.191 +        if not os.path.isfile(policy_filename):
  52.192 +            err("Policy file \'" + policy_filename + "\' not found.")
  52.193 +        else:
  52.194 +            err("Mapping file \'" + map_filename + "\' not found." +
  52.195 +                " Use xm makepolicy to create it.")
  52.196 +
  52.197 +    f = open(map_filename)
  52.198 +    for line in f:
  52.199 +        if policy_reference_entry_re.match(line):
  52.200 +            l = line.split()
  52.201 +            if (len(l) == 2) and (l[1] == policyname):
  52.202 +                map_file_ok = True
  52.203 +        elif primary_entry_re.match(line):
  52.204 +            l = line.split()
  52.205 +            if len(l) == 2:
  52.206 +                primary = l[1]
  52.207 +        elif secondary_entry_re.match(line):
  52.208 +            l = line.split()
  52.209 +            if len(l) == 2:
  52.210 +                secondary = l[1]
  52.211 +    f.close()
  52.212 +    f = open(map_filename)
  52.213 +    if map_file_ok and primary and secondary:
  52.214 +        return (primary, secondary, f, True)
  52.215 +    else:
  52.216 +        err("Mapping file inconsistencies found. Try makepolicy to create a new one.")
  52.217 +
  52.218 +
  52.219 +
  52.220 +def ssidref2label(ssidref_var):
  52.221 +    """
  52.222 +    returns labelname corresponding to ssidref;
  52.223 +    maps current policy to default directory
  52.224 +    to find mapping file
  52.225 +    """
  52.226 +    #1. translated permitted input formats
  52.227 +    if isinstance(ssidref_var, str):
  52.228 +        ssidref_var.strip()
  52.229 +        if ssidref_var[0:2] == "0x":
  52.230 +            ssidref = int(ssidref_var[2:], 16)
  52.231 +        else:
  52.232 +            ssidref = int(ssidref_var)
  52.233 +    elif isinstance(ssidref_var, int):
  52.234 +        ssidref = ssidref_var
  52.235 +    else:
  52.236 +        err("Instance type of ssidref not supported (must be of type 'str' or 'int')")
  52.237 +
  52.238 +    if ssidref == 0:
  52.239 +        from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  52.240 +        return ACM_LABEL_UNLABELED
  52.241 +
  52.242 +    try:
  52.243 +        mapfile_lock()
  52.244 +
  52.245 +        (primary, secondary, f, pol_exists) = getmapfile(None)
  52.246 +        if not f:
  52.247 +            if (pol_exists):
  52.248 +                err("Mapping file for policy not found.\n" +
  52.249 +                    "Please use makepolicy command to create mapping file!")
  52.250 +            else:
  52.251 +                err("Policy file for \'" + active_policy + "\' not found.")
  52.252 +
  52.253 +        #2. get labelnames for both ssidref parts
  52.254 +        pri_ssid = ssidref & 0xffff
  52.255 +        sec_ssid = ssidref >> 16
  52.256 +        pri_null_ssid = NULL_SSIDREF & 0xffff
  52.257 +        sec_null_ssid = NULL_SSIDREF >> 16
  52.258 +        pri_labels = []
  52.259 +        sec_labels = []
  52.260 +        labels = []
  52.261 +
  52.262 +        for line in f:
  52.263 +            l = line.split()
  52.264 +            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  52.265 +                continue
  52.266 +            if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
  52.267 +                pri_labels.append(l[3])
  52.268 +            if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid):
  52.269 +                sec_labels.append(l[3])
  52.270 +        f.close()
  52.271 +    finally:
  52.272 +        mapfile_unlock()
  52.273 +
  52.274 +    #3. get the label that is in both lists (combination must be a single label)
  52.275 +    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid):
  52.276 +        labels = sec_labels
  52.277 +    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid):
  52.278 +        labels = pri_labels
  52.279 +    elif secondary == "NULL":
  52.280 +        labels = pri_labels
  52.281 +    else:
  52.282 +        for i in pri_labels:
  52.283 +            for j in sec_labels:
  52.284 +                if (i==j):
  52.285 +                    labels.append(i)
  52.286 +    if len(labels) != 1:
  52.287 +        err("Label for ssidref \'" +  str(ssidref) +
  52.288 +            "\' unknown or not unique in policy \'" + active_policy + "\'")
  52.289 +
  52.290 +    return labels[0]
  52.291 +
  52.292 +
  52.293 +
  52.294 +def label2ssidref(labelname, policyname, typ):
  52.295 +    """
  52.296 +    returns ssidref corresponding to labelname;
  52.297 +    maps current policy to default directory
  52.298 +    to find mapping file    """
  52.299 +
  52.300 +    if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
  52.301 +        err("Cannot translate labels for \'" + policyname + "\' policy.")
  52.302 +
  52.303 +    allowed_types = ['ANY']
  52.304 +    if typ == 'dom':
  52.305 +        allowed_types.append('VM')
  52.306 +    elif typ == 'res':
  52.307 +        allowed_types.append('RES')
  52.308 +    else:
  52.309 +        err("Invalid type.  Must specify 'dom' or 'res'.")
  52.310 +
  52.311 +    try:
  52.312 +        mapfile_lock()
  52.313 +        (primary, secondary, f, pol_exists) = getmapfile(policyname)
  52.314 +
  52.315 +        #2. get labelnames for ssidref parts and find a common label
  52.316 +        pri_ssid = []
  52.317 +        sec_ssid = []
  52.318 +        for line in f:
  52.319 +            l = line.split()
  52.320 +            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  52.321 +                continue
  52.322 +            if primary and (l[1] in allowed_types) and \
  52.323 +                           (l[2] == primary) and \
  52.324 +                           (l[3] == labelname):
  52.325 +                pri_ssid.append(int(l[4], 16))
  52.326 +            if secondary and (l[1] in allowed_types) and \
  52.327 +                             (l[2] == secondary) and \
  52.328 +                             (l[3] == labelname):
  52.329 +                sec_ssid.append(int(l[4], 16))
  52.330 +        f.close()
  52.331 +        if (typ == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
  52.332 +            pri_ssid.append(NULL_SSIDREF)
  52.333 +        elif (typ == 'res') and (secondary == "CHWALL") and \
  52.334 +             (len(sec_ssid) == 0):
  52.335 +            sec_ssid.append(NULL_SSIDREF)
  52.336 +
  52.337 +        #3. sanity check and composition of ssidref
  52.338 +        if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and \
  52.339 +            (secondary != "NULL")):
  52.340 +            err("Label \'" + labelname + "\' not found.")
  52.341 +        elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
  52.342 +            err("Label \'" + labelname + "\' not unique in policy (policy error)")
  52.343 +        if secondary == "NULL":
  52.344 +            return pri_ssid[0]
  52.345 +        else:
  52.346 +            return (sec_ssid[0] << 16) | pri_ssid[0]
  52.347 +    finally:
  52.348 +       mapfile_unlock()
  52.349 +
  52.350 +
  52.351 +def refresh_ssidref(config):
  52.352 +    """
  52.353 +    looks up ssidref from security field
  52.354 +    and refreshes the value if label exists
  52.355 +    """
  52.356 +    #called by dom0, policy could have changed after xen.utils.security was initialized
  52.357 +    refresh_security_policy()
  52.358 +
  52.359 +    security = None
  52.360 +    if isinstance(config, dict):
  52.361 +        security = config['security']
  52.362 +    elif isinstance(config, list):
  52.363 +        security = sxp.child_value(config, 'security')
  52.364 +    else:
  52.365 +        err("Instance type of config parameter not supported.")
  52.366 +    if not security:
  52.367 +        #nothing to do (no security label attached)
  52.368 +        return config
  52.369 +
  52.370 +    policyname = None
  52.371 +    labelname = None
  52.372 +    # compose new security field
  52.373 +    for idx in range(0, len(security)):
  52.374 +        if security[idx][0] == 'ssidref':
  52.375 +            security.pop(idx)
  52.376 +            break
  52.377 +        elif security[idx][0] == 'access_control':
  52.378 +            for jdx in [1, 2]:
  52.379 +                if security[idx][jdx][0] == 'label':
  52.380 +                    labelname = security[idx][jdx][1]
  52.381 +                elif security[idx][jdx][0] == 'policy':
  52.382 +                    policyname = security[idx][jdx][1]
  52.383 +                else:
  52.384 +                    err("Illegal field in access_control")
  52.385 +    #verify policy is correct
  52.386 +    if active_policy != policyname:
  52.387 +        err("Policy \'" + str(policyname) +
  52.388 +            "\' in label does not match active policy \'"
  52.389 +            + str(active_policy) +"\'!")
  52.390 +
  52.391 +    new_ssidref = label2ssidref(labelname, policyname, 'dom')
  52.392 +    if not new_ssidref:
  52.393 +        err("SSIDREF refresh failed!")
  52.394 +
  52.395 +    security.append([ 'ssidref',str(new_ssidref)])
  52.396 +    security = ['security', security ]
  52.397 +
  52.398 +    for idx in range(0,len(config)):
  52.399 +        if config[idx][0] == 'security':
  52.400 +            config.pop(idx)
  52.401 +            break
  52.402 +        config.append(security)
  52.403 +
  52.404 +
  52.405 +
  52.406 +def get_ssid(domain):
  52.407 +    """
  52.408 +    enables domains to retrieve the label / ssidref of a running domain
  52.409 +    """
  52.410 +    if not on():
  52.411 +        err("No policy active.")
  52.412 +
  52.413 +    if isinstance(domain, str):
  52.414 +        domain_int = int(domain)
  52.415 +    elif isinstance(domain, int):
  52.416 +        domain_int = domain
  52.417 +    else:
  52.418 +        err("Illegal parameter type.")
  52.419 +    try:
  52.420 +        ssid_info = acm.getssid(int(domain_int))
  52.421 +    except:
  52.422 +        err("Cannot determine security information.")
  52.423 +
  52.424 +    if active_policy in ["DEFAULT"]:
  52.425 +        label = "DEFAULT"
  52.426 +    else:
  52.427 +        label = ssidref2label(ssid_info["ssidref"])
  52.428 +    return(ssid_info["policyreference"],
  52.429 +           label,
  52.430 +           ssid_info["policytype"],
  52.431 +           ssid_info["ssidref"])
  52.432 +
  52.433 +
  52.434 +
  52.435 +def get_decision(arg1, arg2):
  52.436 +    """
  52.437 +    enables domains to retrieve access control decisions from
  52.438 +    the hypervisor Access Control Module.
  52.439 +    IN: args format = ['domid', id] or ['ssidref', ssidref]
  52.440 +    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
  52.441 +    """
  52.442 +
  52.443 +    if not on():
  52.444 +        err("No policy active.")
  52.445 +
  52.446 +    #translate labels before calling low-level function
  52.447 +    if arg1[0] == 'access_control':
  52.448 +        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'):
  52.449 +            err("Argument type not supported.")
  52.450 +        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
  52.451 +        arg1 = ['ssidref', str(ssidref)]
  52.452 +    if arg2[0] == 'access_control':
  52.453 +        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'):
  52.454 +            err("Argument type not supported.")
  52.455 +        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
  52.456 +        arg2 = ['ssidref', str(ssidref)]
  52.457 +
  52.458 +    # accept only int or string types for domid and ssidref
  52.459 +    if isinstance(arg1[1], int):
  52.460 +        arg1[1] = str(arg1[1])
  52.461 +    if isinstance(arg2[1], int):
  52.462 +        arg2[1] = str(arg2[1])
  52.463 +    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
  52.464 +        err("Invalid id or ssidref type, string or int required")
  52.465 +
  52.466 +    try:
  52.467 +        decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1],
  52.468 +                                   ACMHOOK_sharing)
  52.469 +    except:
  52.470 +        err("Cannot determine decision.")
  52.471 +
  52.472 +    if decision:
  52.473 +        return decision
  52.474 +    else:
  52.475 +        err("Cannot determine decision (Invalid parameter).")
  52.476 +
  52.477 +
  52.478 +def has_authorization(ssidref):
  52.479 +    """ Check if the domain with the given ssidref has authorization to
  52.480 +        run on this system. To have authoriztion dom0's STE types must
  52.481 +        be a superset of that of the domain's given through its ssidref.
  52.482 +    """
  52.483 +    rc = True
  52.484 +    dom0_ssidref = int(acm.getssid(0)['ssidref'])
  52.485 +    decision = acm.getdecision('ssidref', str(dom0_ssidref),
  52.486 +                               'ssidref', str(ssidref),
  52.487 +                               ACMHOOK_authorization)
  52.488 +    if decision == "DENIED":
  52.489 +        rc = False
  52.490 +    return rc
  52.491 +
  52.492 +
  52.493 +def hv_chg_policy(bin_pol, del_array, chg_array):
  52.494 +    """
  52.495 +        Change the binary policy in the hypervisor
  52.496 +        The 'del_array' and 'chg_array' give hints about deleted ssidrefs
  52.497 +        and changed ssidrefs which can be due to deleted VM labels
  52.498 +        or reordered VM labels
  52.499 +    """
  52.500 +    rc = -xsconstants.XSERR_GENERAL_FAILURE
  52.501 +    errors = ""
  52.502 +    if not on():
  52.503 +        err("No policy active.")
  52.504 +    try:
  52.505 +        rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
  52.506 +    except Exception, e:
  52.507 +        pass
  52.508 +    if len(errors) > 0:
  52.509 +        rc = -xsconstants.XSERR_HV_OP_FAILED
  52.510 +    return rc, errors
  52.511 +
  52.512 +
  52.513 +def make_policy(policy_name):
  52.514 +    policy_file = string.join(string.split(policy_name, "."), "/")
  52.515 +    if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"):
  52.516 +        err("Unknown policy \'" + policy_name + "\'")
  52.517 +
  52.518 +    (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file)
  52.519 +    if ret:
  52.520 +        err("Creating policy failed:\n" + output)
  52.521 +
  52.522 +def load_policy(policy_name):
  52.523 +    global active_policy
  52.524 +    policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/")
  52.525 +    if not os.path.isfile(policy_file + ".bin"):
  52.526 +        if os.path.isfile(policy_file + "-security_policy.xml"):
  52.527 +            err("Binary file does not exist." +
  52.528 +                "Please use makepolicy to build the policy binary.")
  52.529 +        else:
  52.530 +            err("Unknown Policy " + policy_name)
  52.531 +
  52.532 +    #require this policy to be the first or the same as installed
  52.533 +    if active_policy not in ['DEFAULT', policy_name]:
  52.534 +        err("Active policy \'" + active_policy +
  52.535 +            "\' incompatible with new policy \'" + policy_name + "\'")
  52.536 +    (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin")
  52.537 +    if ret:
  52.538 +        err("Loading policy failed:\n" + output)
  52.539 +    else:
  52.540 +        # refresh active policy
  52.541 +        refresh_security_policy()
  52.542 +
  52.543 +
  52.544 +
  52.545 +def dump_policy():
  52.546 +    if active_policy in ['NULL', 'INACTIVE']:
  52.547 +        err("\'" + active_policy + "\' policy. Nothing to dump.")
  52.548 +
  52.549 +    (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
  52.550 +    if ret:
  52.551 +       err("Dumping hypervisor policy failed:\n" + output)
  52.552 +    print output
  52.553 +
  52.554 +
  52.555 +
  52.556 +def list_labels(policy_name, condition):
  52.557 +    if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]:
  52.558 +        err("Current policy \'" + active_policy + "\' has no labels defined.\n")
  52.559 +
  52.560 +    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
  52.561 +    if not f:
  52.562 +        if pol_exists:
  52.563 +            err("Cannot find mapfile for policy \'" + policy_name +
  52.564 +                "\'.\nPlease use makepolicy to create mapping file.")
  52.565 +        else:
  52.566 +            err("Unknown policy \'" + policy_name + "\'")
  52.567 +
  52.568 +    labels = []
  52.569 +    for line in f:
  52.570 +        if condition.match(line):
  52.571 +            label = line.split()[3]
  52.572 +            if label not in labels:
  52.573 +                labels.append(label)
  52.574 +    return labels
  52.575 +
  52.576 +
  52.577 +def get_res_label(resource):
  52.578 +    """Returns resource label information (policytype, label, policy) if
  52.579 +       it exists. Otherwise returns null label and policy.
  52.580 +    """
  52.581 +    def default_res_label():
  52.582 +        ssidref = NULL_SSIDREF
  52.583 +        if on():
  52.584 +            label = ssidref2label(ssidref)
  52.585 +        else:
  52.586 +            label = None
  52.587 +        return (xsconstants.ACM_POLICY_ID, 'NULL', label)
  52.588 +
  52.589 +
  52.590 +    tmp = get_resource_label(resource)
  52.591 +    if len(tmp) == 2:
  52.592 +        policytype = xsconstants.ACM_POLICY_ID
  52.593 +        policy, label = tmp
  52.594 +    elif len(tmp) == 3:
  52.595 +        policytype, policy, label = tmp
  52.596 +    else:
  52.597 +        policytype, policy, label = default_res_label()
  52.598 +
  52.599 +    return (policytype, label, policy)
  52.600 +
  52.601 +
  52.602 +def get_res_security_details(resource):
  52.603 +    """Returns the (label, ssidref, policy) associated with a given
  52.604 +       resource from the global resource label file.
  52.605 +    """
  52.606 +    def default_security_details():
  52.607 +        ssidref = NULL_SSIDREF
  52.608 +        if on():
  52.609 +            label = ssidref2label(ssidref)
  52.610 +        else:
  52.611 +            label = None
  52.612 +        policy = active_policy
  52.613 +        return (label, ssidref, policy)
  52.614 +
  52.615 +    (label, ssidref, policy) = default_security_details()
  52.616 +
  52.617 +    # find the entry associated with this resource
  52.618 +    (policytype, label, policy) = get_res_label(resource)
  52.619 +    if policy == 'NULL':
  52.620 +        log.info("Resource label for "+resource+" not in file, using DEFAULT.")
  52.621 +        return default_security_details()
  52.622 +
  52.623 +    # is this resource label for the running policy?
  52.624 +    if policy == active_policy:
  52.625 +        ssidref = label2ssidref(label, policy, 'res')
  52.626 +    else:
  52.627 +        log.info("Resource label not for active policy, using DEFAULT.")
  52.628 +        return default_security_details()
  52.629 +
  52.630 +    return (label, ssidref, policy)
  52.631 +
  52.632 +def security_label_to_details(seclab):
  52.633 +    """ Convert a Xen-API type of security label into details """
  52.634 +    def default_security_details():
  52.635 +        ssidref = NULL_SSIDREF
  52.636 +        if on():
  52.637 +            label = ssidref2label(ssidref)
  52.638 +        else:
  52.639 +            label = None
  52.640 +        policy = active_policy
  52.641 +        return (label, ssidref, policy)
  52.642 +
  52.643 +    (policytype, policy, label) = seclab.split(":")
  52.644 +
  52.645 +    # is this resource label for the running policy?
  52.646 +    if policy == active_policy:
  52.647 +        ssidref = label2ssidref(label, policy, 'res')
  52.648 +    else:
  52.649 +        log.info("Resource label not for active policy, using DEFAULT.")
  52.650 +        return default_security_details()
  52.651 +
  52.652 +    return (label, ssidref, policy)
  52.653 +
  52.654 +def unify_resname(resource, mustexist=True):
  52.655 +    """Makes all resource locations absolute. In case of physical
  52.656 +    resources, '/dev/' is added to local file names"""
  52.657 +
  52.658 +    if not resource:
  52.659 +        return resource
  52.660 +
  52.661 +    # sanity check on resource name
  52.662 +    try:
  52.663 +        (typ, resfile) = resource.split(":", 1)
  52.664 +    except:
  52.665 +        err("Resource spec '%s' contains no ':' delimiter" % resource)
  52.666 +
  52.667 +    if typ == "tap":
  52.668 +        try:
  52.669 +            (subtype, resfile) = resfile.split(":")
  52.670 +        except:
  52.671 +            err("Resource spec '%s' contains no tap subtype" % resource)
  52.672 +
  52.673 +    import os
  52.674 +    if typ in ["phy", "tap"]:
  52.675 +        if not resfile.startswith("/"):
  52.676 +            resfile = "/dev/" + resfile
  52.677 +        if mustexist:
  52.678 +            stats = os.lstat(resfile)
  52.679 +            if stat.S_ISLNK(stats[stat.ST_MODE]):
  52.680 +                resolved = os.readlink(resfile)
  52.681 +                if resolved[0] != "/":
  52.682 +                    resfile = os.path.join(os.path.dirname(resfile), resolved)
  52.683 +                    resfile = os.path.abspath(resfile)
  52.684 +                else:
  52.685 +                    resfile = resolved
  52.686 +                stats = os.lstat(resfile)
  52.687 +            if not (stat.S_ISBLK(stats[stat.ST_MODE])):
  52.688 +                err("Invalid resource")
  52.689 +
  52.690 +    if typ in [ "file", "tap" ]:
  52.691 +        if mustexist:
  52.692 +            stats = os.lstat(resfile)
  52.693 +            if stat.S_ISLNK(stats[stat.ST_MODE]):
  52.694 +                resfile = os.readlink(resfile)
  52.695 +                stats = os.lstat(resfile)
  52.696 +            if not stat.S_ISREG(stats[stat.ST_MODE]):
  52.697 +                err("Invalid resource")
  52.698 +
  52.699 +    #file: resources must specified with absolute path
  52.700 +    #vlan resources don't start with '/'
  52.701 +    if typ != "vlan":
  52.702 +        if (not resfile.startswith("/")) or \
  52.703 +           (mustexist and not os.path.exists(resfile)):
  52.704 +            err("Invalid resource.")
  52.705 +
  52.706 +    # from here on absolute file names with resources
  52.707 +    if typ == "tap":
  52.708 +        typ = typ + ":" + subtype
  52.709 +    resource = typ + ":" + resfile
  52.710 +    return resource
  52.711 +
  52.712 +
  52.713 +def res_security_check(resource, domain_label):
  52.714 +    """Checks if the given resource can be used by the given domain
  52.715 +       label.  Returns 1 if the resource can be used, otherwise 0.
  52.716 +    """
  52.717 +    rtnval = 1
  52.718 +
  52.719 +    # if security is on, ask the hypervisor for a decision
  52.720 +    if on():
  52.721 +        #build canonical resource name
  52.722 +        resource = unify_resname(resource)
  52.723 +
  52.724 +        (label, ssidref, policy) = get_res_security_details(resource)
  52.725 +        domac = ['access_control']
  52.726 +        domac.append(['policy', active_policy])
  52.727 +        domac.append(['label', domain_label])
  52.728 +        domac.append(['type', 'dom'])
  52.729 +        decision = get_decision(domac, ['ssidref', str(ssidref)])
  52.730 +
  52.731 +        # provide descriptive error messages
  52.732 +        if decision == 'DENIED':
  52.733 +            if label == ssidref2label(NULL_SSIDREF):
  52.734 +                raise ACMError("Resource '"+resource+"' is not labeled")
  52.735 +                rtnval = 0
  52.736 +            else:
  52.737 +                raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed")
  52.738 +                rtnval = 0
  52.739 +
  52.740 +    # security is off, make sure resource isn't labeled
  52.741 +    else:
  52.742 +        # Note, we can't canonicalise the resource here, because people using
  52.743 +        # xm without ACM are free to use relative paths.
  52.744 +        (policytype, label, policy) = get_res_label(resource)
  52.745 +        if policy != 'NULL':
  52.746 +            raise ACMError("Security is off, but '"+resource+"' is labeled")
  52.747 +            rtnval = 0
  52.748 +
  52.749 +    return rtnval
  52.750 +
  52.751 +def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
  52.752 +    """Checks if the given resource can be used by the given domain
  52.753 +       label.  Returns 1 if the resource can be used, otherwise 0.
  52.754 +    """
  52.755 +    rtnval = 1
  52.756 +    # if security is on, ask the hypervisor for a decision
  52.757 +    if on():
  52.758 +        typ, dpolicy, domain_label = xapi_dom_label.split(":")
  52.759 +        if not dpolicy or not domain_label:
  52.760 +            raise VmError("VM security label in wrong format.")
  52.761 +        if active_policy != rpolicy:
  52.762 +            raise VmError("Resource's policy '%s' != active policy '%s'" %
  52.763 +                          (rpolicy, active_policy))
  52.764 +        domac = ['access_control']
  52.765 +        domac.append(['policy', active_policy])
  52.766 +        domac.append(['label', domain_label])
  52.767 +        domac.append(['type', 'dom'])
  52.768 +        decision = get_decision(domac, ['ssidref', str(rssidref)])
  52.769 +
  52.770 +        log.info("Access Control Decision : %s" % decision)
  52.771 +        # provide descriptive error messages
  52.772 +        if decision == 'DENIED':
  52.773 +            if rlabel == ssidref2label(NULL_SSIDREF):
  52.774 +                #raise ACMError("Resource is not labeled")
  52.775 +                rtnval = 0
  52.776 +            else:
  52.777 +                #raise ACMError("Permission denied for resource because label '"+rlabel+"' is not allowed")
  52.778 +                rtnval = 0
  52.779 +
  52.780 +    # security is off, make sure resource isn't labeled
  52.781 +    else:
  52.782 +        # Note, we can't canonicalise the resource here, because people using
  52.783 +        # xm without ACM are free to use relative paths.
  52.784 +        if rpolicy != 'NULL':
  52.785 +            #raise ACMError("Security is off, but resource is labeled")
  52.786 +            rtnval = 0
  52.787 +
  52.788 +    return rtnval
  52.789 +
  52.790 +
  52.791 +def validate_label(label, policyref):
  52.792 +    """
  52.793 +       Make sure that this label is part of the currently enforced policy
  52.794 +       and that it reference the current policy.
  52.795 +    """
  52.796 +    rc = xsconstants.XSERR_SUCCESS
  52.797 +    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  52.798 +    curpol = XSPolicyAdminInstance().get_loaded_policy()
  52.799 +    if not curpol or curpol.get_name() != policyref:
  52.800 +        rc = -xsconstants.XSERR_BAD_LABEL
  52.801 +    else:
  52.802 +        try:
  52.803 +            label2ssidref(label, curpol.get_name() , 'res')
  52.804 +        except:
  52.805 +            rc = -xsconstants.XSERR_BAD_LABEL
  52.806 +    return rc
  52.807 +
  52.808 +
  52.809 +def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
  52.810 +    """Assign a resource label to a resource
  52.811 +    @param resource: The name of a resource, i.e., "phy:/dev/hda", or
  52.812 +              "tap:qcow:/path/to/file.qcow"
  52.813 +
  52.814 +    @param reslabel_xapi: A resource label foramtted as in all other parts of
  52.815 +                          the Xen-API, i.e., ACM:xm-test:blue"
  52.816 +    @rtype: int
  52.817 +    @return Success (0) or failure value (< 0)
  52.818 +    """
  52.819 +    olabel = ""
  52.820 +    if reslabel_xapi == "":
  52.821 +        return rm_resource_label(resource, oldlabel_xapi)
  52.822 +    typ, policyref, label = reslabel_xapi.split(":")
  52.823 +    if typ != xsconstants.ACM_POLICY_ID:
  52.824 +        return -xsconstants.XSERR_WRONG_POLICY_TYPE
  52.825 +    if not policyref or not label:
  52.826 +        return -xsconstants.XSERR_BAD_LABEL_FORMAT
  52.827 +    if oldlabel_xapi not in [ "" ]:
  52.828 +        tmp = oldlabel_xapi.split(":")
  52.829 +        if len(tmp) != 3:
  52.830 +            return -xsconstants.XSERR_BAD_LABEL_FORMAT
  52.831 +        otyp, opolicyref, olabel = tmp
  52.832 +        # Only ACM is supported
  52.833 +        if otyp != xsconstants.ACM_POLICY_ID  and \
  52.834 +           otyp != xsconstants.INVALID_POLICY_PREFIX + \
  52.835 +                   xsconstants.ACM_POLICY_ID:
  52.836 +            return -xsconstants.XSERR_WRONG_POLICY_TYPE
  52.837 +    rc = validate_label(label, policyref)
  52.838 +    if rc != xsconstants.XSERR_SUCCESS:
  52.839 +        return rc
  52.840 +    return set_resource_label(resource, typ, policyref, label, olabel)
  52.841 +
  52.842 +
  52.843 +def is_resource_in_use(resource):
  52.844 +    """
  52.845 +       Domain-0 'owns' resources of type 'VLAN', the rest are owned by
  52.846 +       the guests.
  52.847 +    """
  52.848 +    from xen.xend import XendDomain
  52.849 +    lst = []
  52.850 +    if resource.startswith('vlan'):
  52.851 +        from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  52.852 +        curpol = XSPolicyAdminInstance().get_loaded_policy()
  52.853 +        policytype, label, policy = get_res_label(resource)
  52.854 +        if curpol and \
  52.855 +           policytype == xsconstants.ACM_POLICY_ID and \
  52.856 +           policy == curpol.get_name() and \
  52.857 +           label in curpol.policy_get_resourcelabel_names():
  52.858 +            # VLAN is in use.
  52.859 +            lst.append(XendDomain.instance().
  52.860 +                         get_vm_by_uuid(XendDomain.DOM0_UUID))
  52.861 +    else:
  52.862 +        dominfos = XendDomain.instance().list('all')
  52.863 +        for dominfo in dominfos:
  52.864 +            if is_resource_in_use_by_dom(dominfo, resource):
  52.865 +                lst.append(dominfo)
  52.866 +    return lst
  52.867 +
  52.868 +def devices_equal(res1, res2, mustexist=True):
  52.869 +    """ Determine whether two devices are equal """
  52.870 +    return (unify_resname(res1, mustexist) ==
  52.871 +            unify_resname(res2, mustexist))
  52.872 +
  52.873 +def is_resource_in_use_by_dom(dominfo, resource):
  52.874 +    """ Determine whether a resources is in use by a given domain
  52.875 +        @return True or False
  52.876 +    """
  52.877 +    if not dominfo.domid:
  52.878 +        return False
  52.879 +    if dominfo._stateGet() not in [ DOM_STATE_RUNNING ]:
  52.880 +        return False
  52.881 +    devs = dominfo.info['devices']
  52.882 +    uuids = devs.keys()
  52.883 +    for uuid in uuids:
  52.884 +        dev = devs[uuid]
  52.885 +        if len(dev) >= 2 and dev[1].has_key('uname'):
  52.886 +            # dev[0] is type, i.e. 'vbd'
  52.887 +            if devices_equal(dev[1]['uname'], resource, mustexist=False):
  52.888 +                log.info("RESOURCE IN USE: Domain %d uses %s." %
  52.889 +                         (dominfo.domid, resource))
  52.890 +                return True
  52.891 +    return False
  52.892 +
  52.893 +
  52.894 +def get_domain_resources(dominfo):
  52.895 +    """ Collect all resources of a domain in a map where each entry of
  52.896 +        the map is a list.
  52.897 +        Entries are strored in the following formats:
  52.898 +          tap:qcow:/path/xyz.qcow
  52.899 +    """
  52.900 +    resources = { 'vbd' : [], 'tap' : [], 'vif' : []}
  52.901 +    devs = dominfo.info['devices']
  52.902 +    uuids = devs.keys()
  52.903 +    for uuid in uuids:
  52.904 +        dev = devs[uuid]
  52.905 +        typ = dev[0]
  52.906 +        if typ in [ 'vbd', 'tap' ]:
  52.907 +            resources[typ].append(dev[1]['uname'])
  52.908 +        if typ in [ 'vif' ]:
  52.909 +            sec_lab = dev[1].get('security_label')
  52.910 +            if sec_lab:
  52.911 +                resources[typ].append(sec_lab)
  52.912 +            else:
  52.913 +                # !!! This should really get the label of the domain
  52.914 +                # or at least a resource label that has the same STE type
  52.915 +                # as the domain has
  52.916 +                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  52.917 +                resources[typ].append("%s:%s:%s" %
  52.918 +                                      (xsconstants.ACM_POLICY_ID,
  52.919 +                                       active_policy,
  52.920 +                                       ACM_LABEL_UNLABELED))
  52.921 +
  52.922 +    return resources
  52.923 +
  52.924 +
  52.925 +def resources_compatible_with_vmlabel(xspol, dominfo, vmlabel):
  52.926 +    """
  52.927 +       Check whether the resources' labels are compatible with the
  52.928 +       given VM label. This is a function to be used when for example
  52.929 +       a running domain is to get the new label 'vmlabel'
  52.930 +    """
  52.931 +    if not xspol:
  52.932 +        return False
  52.933 +
  52.934 +    try:
  52.935 +        __resfile_lock.acquire()
  52.936 +        try:
  52.937 +            access_control = dictio.dict_read("resources",
  52.938 +                                              res_label_filename)
  52.939 +        except:
  52.940 +            # No labeled resources -> must be compatible
  52.941 +            return True
  52.942 +        return __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  52.943 +                                                   access_control)
  52.944 +    finally:
  52.945 +        __resfile_lock.release()
  52.946 +    return False
  52.947 +
  52.948 +
  52.949 +def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  52.950 +                                        access_control,
  52.951 +                                        is_policy_update=False):
  52.952 +    """
  52.953 +        Check whether the resources' labels are compatible with the
  52.954 +        given VM label. The access_control parameter provides a
  52.955 +        dictionary of the resource name to resource label mappings
  52.956 +        under which the evaluation should be done.
  52.957 +        Call this only for a paused or running domain.
  52.958 +    """
  52.959 +    def collect_labels(reslabels, s_label, polname):
  52.960 +        if len(s_label) != 3 or polname != s_label[1]:
  52.961 +            return False
  52.962 +        label = s_label[2]
  52.963 +        if not label in reslabels:
  52.964 +            reslabels.append(label)
  52.965 +        return True
  52.966 +
  52.967 +    resources = get_domain_resources(dominfo)
  52.968 +    reslabels = []  # all resource labels
  52.969 +
  52.970 +    polname = xspol.get_name()
  52.971 +    for key, value in resources.items():
  52.972 +        if key in [ 'vbd', 'tap' ]:
  52.973 +            for res in resources[key]:
  52.974 +                try:
  52.975 +                    label = access_control[res]
  52.976 +                    if not collect_labels(reslabels, label, polname):
  52.977 +                        return False
  52.978 +                except:
  52.979 +                    return False
  52.980 +        elif key in [ 'vif' ]:
  52.981 +            for xapi_label in value:
  52.982 +                label = xapi_label.split(":")
  52.983 +                from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  52.984 +                if not (is_policy_update and \
  52.985 +                        label[2] == ACM_LABEL_UNLABELED):
  52.986 +                    if not collect_labels(reslabels, label, polname):
  52.987 +                        return False
  52.988 +        else:
  52.989 +            log.error("Unhandled device type: %s" % key)
  52.990 +            return False
  52.991 +
  52.992 +    # Check that all resource labes have a common STE type with the
  52.993 +    # vmlabel
  52.994 +    if len(reslabels) > 0:
  52.995 +        rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
  52.996 +    else:
  52.997 +        rc = True
  52.998 +    log.info("vmlabel=%s, reslabels=%s, rc=%s" %
  52.999 +             (vmlabel, reslabels, str(rc)))
 52.1000 +    return rc;
 52.1001 +
 52.1002 +def set_resource_label(resource, policytype, policyref, reslabel, \
 52.1003 +                       oreslabel = None):
 52.1004 +    """Assign a label to a resource
 52.1005 +       If the old label (oreslabel) is given, then the resource must have
 52.1006 +       that old label.
 52.1007 +       A resource label may be changed if
 52.1008 +       - the resource is not in use
 52.1009 +    @param resource  : The name of a resource, i.e., "phy:/dev/hda"
 52.1010 +    @param policyref : The name of the policy
 52.1011 +    @param reslabel     : the resource label within the policy
 52.1012 +    @param oreslabel    : optional current resource label
 52.1013 +
 52.1014 +    @rtype: int
 52.1015 +    @return Success (0) or failure value (< 0)
 52.1016 +    """
 52.1017 +    try:
 52.1018 +        resource = unify_resname(resource, mustexist=False)
 52.1019 +    except Exception:
 52.1020 +        return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
 52.1021 +
 52.1022 +    domains = is_resource_in_use(resource)
 52.1023 +    if len(domains) > 0:
 52.1024 +        return -xsconstants.XSERR_RESOURCE_IN_USE
 52.1025 +
 52.1026 +    try:
 52.1027 +        __resfile_lock.acquire()
 52.1028 +        access_control = {}
 52.1029 +        try:
 52.1030 +             access_control = dictio.dict_read("resources", res_label_filename)
 52.1031 +        except:
 52.1032 +            pass
 52.1033 +        if oreslabel:
 52.1034 +            if not access_control.has_key(resource):
 52.1035 +                return -xsconstants.XSERR_BAD_LABEL
 52.1036 +            tmp = access_control[resource]
 52.1037 +            if len(tmp) != 3:
 52.1038 +                return -xsconstants.XSERR_BAD_LABEL
 52.1039 +            if tmp[2] != oreslabel:
 52.1040 +                return -xsconstants.XSERR_BAD_LABEL
 52.1041 +        if reslabel != "":
 52.1042 +            new_entry = { resource : tuple([policytype, policyref, reslabel])}
 52.1043 +            access_control.update(new_entry)
 52.1044 +        else:
 52.1045 +            if access_control.has_key(resource):
 52.1046 +                del access_control[resource]
 52.1047 +        dictio.dict_write(access_control, "resources", res_label_filename)
 52.1048 +    finally:
 52.1049 +        __resfile_lock.release()
 52.1050 +    return xsconstants.XSERR_SUCCESS
 52.1051 +
 52.1052 +def rm_resource_label(resource, oldlabel_xapi):
 52.1053 +    """Remove a resource label from a physical resource
 52.1054 +    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 52.1055 +
 52.1056 +    @rtype: int
 52.1057 +    @return Success (0) or failure value (< 0)
 52.1058 +    """
 52.1059 +    tmp = oldlabel_xapi.split(":")
 52.1060 +    if len(tmp) != 3:
 52.1061 +        return -xsconstants.XSERR_BAD_LABEL_FORMAT
 52.1062 +    otyp, opolicyref, olabel = tmp
 52.1063 +    # Only ACM is supported
 52.1064 +    if otyp != xsconstants.ACM_POLICY_ID and \
 52.1065 +       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:
 52.1066 +        return -xsconstants.XSERR_WRONG_POLICY_TYPE
 52.1067 +    return set_resource_label(resource, "", "", "", olabel)
 52.1068 +
 52.1069 +def get_resource_label_xapi(resource):
 52.1070 +    """Get the assigned resource label of a physical resource
 52.1071 +      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"
 52.1072 +
 52.1073 +      @rtype: string
 52.1074 +      @return the string representing policy type, policy name and label of
 52.1075 +              the resource
 52.1076 +    """
 52.1077 +    res = get_resource_label(resource)
 52.1078 +    return format_resource_label(res)
 52.1079 +
 52.1080 +def format_resource_label(res):
 52.1081 +    if res:
 52.1082 +        if len(res) == 2:
 52.1083 +            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]
 52.1084 +        if len(res) == 3:
 52.1085 +            return ":".join(res)
 52.1086 +    return ""
 52.1087 +
 52.1088 +def get_resource_label(resource):
 52.1089 +    """Get the assigned resource label of a given resource
 52.1090 +    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 52.1091 +
 52.1092 +    @rtype: list
 52.1093 +    @return tuple of (policy name, resource label), i.e., (xm-test, blue)
 52.1094 +    """
 52.1095 +    try:
 52.1096 +        resource = unify_resname(resource, mustexist=False)
 52.1097 +    except Exception:
 52.1098 +        return []
 52.1099 +
 52.1100 +    reslabel_map = get_labeled_resources()
 52.1101 +
 52.1102 +    if reslabel_map.has_key(resource):
 52.1103 +        return list(reslabel_map[resource])
 52.1104 +    else:
 52.1105 +        #Try to resolve each label entry
 52.1106 +        for key, value in reslabel_map.items():
 52.1107 +            try:
 52.1108 +                if resource == unify_resname(key):
 52.1109 +                    return list(value)
 52.1110 +            except:
 52.1111 +                pass
 52.1112 +
 52.1113 +    return []
 52.1114 +
 52.1115 +
 52.1116 +def get_labeled_resources_xapi():
 52.1117 +    """ Get a map of all labeled resource with the labels formatted in the
 52.1118 +        xen-api resource label format.
 52.1119 +    """
 52.1120 +    reslabel_map = get_labeled_resources()
 52.1121 +    for key, labeldata in reslabel_map.items():
 52.1122 +        reslabel_map[key] = format_resource_label(labeldata)
 52.1123 +    return reslabel_map
 52.1124 +
 52.1125 +
 52.1126 +def get_labeled_resources():
 52.1127 +    """Get a map of all labeled resources
 52.1128 +    @rtype: list
 52.1129 +    @return list of labeled resources
 52.1130 +    """
 52.1131 +    try:
 52.1132 +        __resfile_lock.acquire()
 52.1133 +        try:
 52.1134 +            access_control = dictio.dict_read("resources", res_label_filename)
 52.1135 +        except:
 52.1136 +            return {}
 52.1137 +    finally:
 52.1138 +        __resfile_lock.release()
 52.1139 +    return access_control
 52.1140 +
 52.1141 +
 52.1142 +def relabel_domains(relabel_list):
 52.1143 +    """
 52.1144 +      Relabel the given domains to have a new ssidref.
 52.1145 +      @param relabel_list: a list containing tuples of domid, ssidref
 52.1146 +                           example: [ [0, 0x00020002] ]
 52.1147 +    """
 52.1148 +    rel_rules = ""
 52.1149 +    for r in relabel_list:
 52.1150 +        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",
 52.1151 +                r[0], r[1])
 52.1152 +        rel_rules += struct.pack("ii", r[0], r[1])
 52.1153 +    try:
 52.1154 +        rc, errors = acm.relabel_domains(rel_rules)
 52.1155 +    except Exception, e:
 52.1156 +        log.info("Error after relabel_domains: %s" % str(e))
 52.1157 +        rc = -xsconstants.XSERR_GENERAL_FAILURE
 52.1158 +        errors = ""
 52.1159 +    if (len(errors) > 0):
 52.1160 +        rc = -xsconstants.XSERR_HV_OP_FAILED
 52.1161 +    return rc, errors
 52.1162 +
 52.1163 +
 52.1164 +def change_acm_policy(bin_pol, del_array, chg_array,
 52.1165 +                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):
 52.1166 +    """
 52.1167 +       Change the ACM policy of the system by relabeling
 52.1168 +       domains and resources first and doing some access checks.
 52.1169 +       Then update the policy in the hypervisor. If this is all successful,
 52.1170 +       relabel the domains permanently and commit the relabed resources.
 52.1171 +
 52.1172 +       Need to do / check the following:
 52.1173 +        - relabel all resources where there is a 'from' field in
 52.1174 +          the policy. [ NOT DOING THIS: and mark those as unlabeled where the label
 52.1175 +          does not appear in the new policy anymore (deletion) ]
 52.1176 +        - relabel all VMs where there is a 'from' field in the
 52.1177 +          policy and mark those as unlabeled where the label
 52.1178 +          does not appear in the new policy anymore; no running
 52.1179 +          or paused VM may be unlabeled through this
 52.1180 +        - check that under the new labeling conditions the VMs
 52.1181 +          still have access to their resources as before. Unlabeled
 52.1182 +          resources are inaccessible. If this check fails, the
 52.1183 +          update failed.
 52.1184 +        - Attempt changes in the hypervisor; if this step fails,
 52.1185 +          roll back the relabeling of resources and VMs
 52.1186 +        - Make the relabeling of resources and VMs permanent
 52.1187 +    """
 52.1188 +    rc = xsconstants.XSERR_SUCCESS
 52.1189 +
 52.1190 +    domain_label_map = {}
 52.1191 +    new_policyname = new_acmpol.get_name()
 52.1192 +    new_policytype = new_acmpol.get_type_name()
 52.1193 +    cur_policyname = cur_acmpol.get_name()
 52.1194 +    cur_policytype = cur_acmpol.get_type_name()
 52.1195 +    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()
 52.1196 +    errors=""
 52.1197 +
 52.1198 +    try:
 52.1199 +        __resfile_lock.acquire()
 52.1200 +        mapfile_lock()
 52.1201 +
 52.1202 +        # Get all domains' dominfo.
 52.1203 +        from xen.xend import XendDomain
 52.1204 +        dominfos = XendDomain.instance().list('all')
 52.1205 +
 52.1206 +        log.info("----------------------------------------------")
 52.1207 +        # relabel resources
 52.1208 +
 52.1209 +        access_control = {}
 52.1210 +        try:
 52.1211 +            access_control = dictio.dict_read("resources", res_label_filename)
 52.1212 +        except:
 52.1213 +            pass
 52.1214 +        for key, labeldata in access_control.items():
 52.1215 +            if len(labeldata) == 2:
 52.1216 +                policy, label = labeldata
 52.1217 +                policytype = xsconstants.ACM_POLICY_ID
 52.1218 +            elif len(labeldata) == 3:
 52.1219 +                policytype, policy, label = labeldata
 52.1220 +            else:
 52.1221 +                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""
 52.1222 +
 52.1223 +            if policytype != cur_policytype or \
 52.1224 +               policy     != cur_policyname:
 52.1225 +                continue
 52.1226 +
 52.1227 +            # label been renamed or deleted?
 52.1228 +            if reslabel_map.has_key(label) and cur_policyname == policy:
 52.1229 +                label = reslabel_map[label]
 52.1230 +            elif label not in polnew_reslabels:
 52.1231 +                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 52.1232 +            # Update entry
 52.1233 +            access_control[key] = \
 52.1234 +                   tuple([ policytype, new_policyname, label ])
 52.1235 +
 52.1236 +        # All resources have new labels in the access_control map
 52.1237 +        # There may still be labels in there that are invalid now.
 52.1238 +
 52.1239 +        # Do this in memory without writing to disk:
 52.1240 +        #  - Relabel all domains independent of whether they are running
 52.1241 +        #    or not
 52.1242 +        #  - later write back to config files
 52.1243 +        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()
 52.1244 +
 52.1245 +        for dominfo in dominfos:
 52.1246 +            sec_lab = dominfo.get_security_label()
 52.1247 +            if not sec_lab:
 52.1248 +                continue
 52.1249 +            policytype, policy, vmlabel = sec_lab.split(":")
 52.1250 +            name  = dominfo.getName()
 52.1251 +
 52.1252 +            if policytype != cur_policytype or \
 52.1253 +               policy     != cur_policyname:
 52.1254 +                continue
 52.1255 +
 52.1256 +            new_vmlabel = vmlabel
 52.1257 +            if vmlabel_map.has_key(vmlabel):
 52.1258 +                new_vmlabel = vmlabel_map[vmlabel]
 52.1259 +            if new_vmlabel not in polnew_vmlabels:
 52.1260 +                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 52.1261 +            new_seclab = "%s:%s:%s" % \
 52.1262 +                    (policytype, new_policyname, new_vmlabel)
 52.1263 +
 52.1264 +            domain_label_map[dominfo] = [ sec_lab, new_seclab ]
 52.1265 +
 52.1266 +            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
 52.1267 +                compatible = __resources_compatible_with_vmlabel(new_acmpol,
 52.1268 +                                                      dominfo,
 52.1269 +                                                      new_vmlabel,
 52.1270 +                                                      access_control,
 52.1271 +                                                      is_policy_update=True)
 52.1272 +                log.info("Domain %s with new label '%s' can access its "
 52.1273 +                         "resources? : %s" %
 52.1274 +                         (name, new_vmlabel, str(compatible)))
 52.1275 +                log.info("VM labels in new policy: %s" %
 52.1276 +                         new_acmpol.policy_get_virtualmachinelabel_names())
 52.1277 +                if not compatible:
 52.1278 +                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
 52.1279 +
 52.1280 +        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)
 52.1281 +        if rc == 0:
 52.1282 +            # Write the relabeled resources back into the file
 52.1283 +            dictio.dict_write(access_control, "resources", res_label_filename)
 52.1284 +            # Properly update all VMs to their new labels
 52.1285 +            for dominfo, labels in domain_label_map.items():
 52.1286 +                sec_lab, new_seclab = labels
 52.1287 +                if sec_lab != new_seclab:
 52.1288 +                    log.info("Updating domain %s to new label '%s'." % \
 52.1289 +                             (dominfo.getName(), new_seclab))
 52.1290 +                    # This better be working!
 52.1291 +                    res = dominfo.set_security_label(new_seclab,
 52.1292 +                                                     sec_lab,
 52.1293 +                                                     new_acmpol,
 52.1294 +                                                     cur_acmpol)
 52.1295 +                    if res[0] != xsconstants.XSERR_SUCCESS:
 52.1296 +                        log.info("ERROR: Could not chg label on domain %s: %s" %
 52.1297 +                                 (dominfo.getName(),
 52.1298 +                                  xsconstants.xserr2string(-int(res[0]))))
 52.1299 +    finally:
 52.1300 +        log.info("----------------------------------------------")
 52.1301 +        mapfile_unlock()
 52.1302 +        __resfile_lock.release()
 52.1303 +
 52.1304 +    return rc, errors
 52.1305 +
 52.1306 +def parse_security_label(security_label):
 52.1307 +    tmp = security_label.split(":")
 52.1308 +    if len(tmp) != 3:
 52.1309 +        return ""
 52.1310 +    else:
 52.1311 +        return security_label
 52.1312 +
 52.1313 +def set_security_label(policy, label):
 52.1314 +    policytype = xsconstants.ACM_POLICY_ID
 52.1315 +    if label != "" and policy != "":
 52.1316 +        return "%s:%s:%s" % (policytype, policy, label)
 52.1317 +    else:
 52.1318 +        return ""
 52.1319 +
 52.1320 +def ssidref2security_label(ssidref):
 52.1321 +    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
 52.1322 +    return XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/tools/python/xen/util/xsm/dummy/__init__.py	Thu Sep 06 12:05:15 2007 -0600
    53.3 @@ -0,0 +1,1 @@
    53.4 + 
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/tools/python/xen/util/xsm/dummy/dummy.py	Thu Sep 06 12:05:15 2007 -0600
    54.3 @@ -0,0 +1,53 @@
    54.4 +import sys
    54.5 +
    54.6 +class XSMError(Exception):
    54.7 +    def __init__(self,value):
    54.8 +        self.value = value
    54.9 +    def __str__(self):
   54.10 +        return repr(self.value)
   54.11 +
   54.12 +policy_dir_prefix = "";
   54.13 +active_policy = "";
   54.14 +NULL_SSIDREF = 0;
   54.15 +
   54.16 +def err(msg):
   54.17 +    """Raise XSM-dummy exception.
   54.18 +    """
   54.19 +    sys.stderr.write("XSM-dummyError: " + msg + "\n")
   54.20 +    raise XSMError(msg)
   54.21 +
   54.22 +def on():
   54.23 +    return 0
   54.24 +
   54.25 +def ssidref2label(ssidref):
   54.26 +    return 0
   54.27 +
   54.28 +def label2ssidref(label, policy, type):
   54.29 +    return 0
   54.30 +
   54.31 +def res_security_check(resource, domain_label):
   54.32 +    return 1
   54.33 +
   54.34 +def get_res_security_details(resource):
   54.35 +    return ("","","")
   54.36 +
   54.37 +def get_res_label(resource):
   54.38 +    return ("","")
   54.39 +
   54.40 +def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
   54.41 +    return 1
   54.42 +
   54.43 +def parse_security_label(security_label):
   54.44 +    return ""
   54.45 +
   54.46 +def calc_dom_ssidref_from_info(info):
   54.47 +    return ""
   54.48 +
   54.49 +def set_security_label(policy, label):
   54.50 +     return ""
   54.51 +
   54.52 +def ssidref2security_label(ssidref):
   54.53 +    return ""
   54.54 +
   54.55 +def has_authorization(ssidref):
   54.56 +    return True
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/tools/python/xen/util/xsm/flask/__init__.py	Thu Sep 06 12:05:15 2007 -0600
    55.3 @@ -0,0 +1,1 @@
    55.4 + 
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tools/python/xen/util/xsm/flask/flask.py	Thu Sep 06 12:05:15 2007 -0600
    56.3 @@ -0,0 +1,37 @@
    56.4 +import sys
    56.5 +from xen.lowlevel import flask
    56.6 +from xen.xend import sxp
    56.7 +
    56.8 +def err(msg):
    56.9 +    """Raise XSM-Flask exception.
   56.10 +    """
   56.11 +    sys.stderr.write("XSM-FlaskError: " + msg + "\n")
   56.12 +    raise XSMError(msg)
   56.13 +
   56.14 +def on():
   56.15 +    return 1
   56.16 +
   56.17 +def ssidref2label(ssidref):
   56.18 +    try:
   56.19 +        return flask.flask_sid_to_context(ssidref)
   56.20 +    except:
   56.21 +        return ""
   56.22 +
   56.23 +def label2ssidref(label, policy, type):
   56.24 +    try:
   56.25 +        return flask.flask_context_to_sid(label)
   56.26 +    except:
   56.27 +        return ""
   56.28 +
   56.29 +def parse_security_label(security_label):
   56.30 +    return security_label
   56.31 +
   56.32 +def calc_dom_ssidref_from_info(info):
   56.33 +    ssidref = label2ssidref(info['security_label'], "", "")
   56.34 +    return ssidref
   56.35 +
   56.36 +def set_security_label(policy, label):
   56.37 +    return label
   56.38 +
   56.39 +def ssidref2security_label(ssidref):
   56.40 +    return ssidref2label(ssidref)
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/tools/python/xen/util/xsm/xsm_core.py	Thu Sep 06 12:05:15 2007 -0600
    57.3 @@ -0,0 +1,7 @@
    57.4 +import sys
    57.5 +import xen.util.xsm.dummy.dummy as dummy
    57.6 +
    57.7 +def xsm_init(self):
    57.8 +    for op in dir(dummy):
    57.9 +        if not hasattr(self, op):
   57.10 +            setattr(self, op, getattr(dummy, op, None))
    58.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Thu Sep 06 09:05:26 2007 -0600
    58.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Thu Sep 06 12:05:15 2007 -0600
    58.3 @@ -16,7 +16,7 @@ from xen.util.xpopen import xPopen3
    58.4  import xen.util.auxbin
    58.5  import xen.lowlevel.xc
    58.6  
    58.7 -from xen.xend import balloon, sxp
    58.8 +from xen.xend import balloon, sxp, image
    58.9  from xen.xend.XendError import XendError, VmError
   58.10  from xen.xend.XendLogging import log
   58.11  from xen.xend.XendConfig import XendConfig
   58.12 @@ -181,8 +181,6 @@ def restore(xd, fd, dominfo = None, paus
   58.13      assert store_port
   58.14      assert console_port
   58.15  
   58.16 -    nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 
   58.17 -
   58.18      # if hvm, pass mem size to calculate the store_mfn
   58.19      image_cfg = dominfo.info.get('image', {})
   58.20      is_hvm = dominfo.info.is_hvm()
   58.21 @@ -196,19 +194,32 @@ def restore(xd, fd, dominfo = None, paus
   58.22          pae  = 0
   58.23  
   58.24      try:
   58.25 -        shadow = dominfo.info['shadow_memory']
   58.26 +        restore_image = image.create(dominfo, dominfo.info)
   58.27 +        memory = restore_image.getRequiredAvailableMemory(
   58.28 +            dominfo.info['memory_dynamic_max'] / 1024)
   58.29 +        maxmem = restore_image.getRequiredAvailableMemory(
   58.30 +            dominfo.info['memory_static_max'] / 1024)
   58.31 +        shadow = restore_image.getRequiredShadowMemory(
   58.32 +            dominfo.info['shadow_memory'] / 1024,
   58.33 +            dominfo.info['memory_static_max'] / 1024)
   58.34 +
   58.35          log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, ",
   58.36                    dominfo.info['shadow_memory'],
   58.37                    dominfo.info['memory_static_max'],
   58.38                    dominfo.info['memory_static_min'])
   58.39  
   58.40 -        balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024)
   58.41 +        # Round shadow up to a multiple of a MiB, as shadow_mem_control
   58.42 +        # takes MiB and we must not round down and end up under-providing.
   58.43 +        shadow = ((shadow + 1023) / 1024) * 1024
   58.44  
   58.45 -        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow)
   58.46 +        # set memory limit
   58.47 +        xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
   58.48 +
   58.49 +        balloon.free(memory + shadow)
   58.50 +
   58.51 +        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow / 1024)
   58.52          dominfo.info['shadow_memory'] = shadow_cur
   58.53  
   58.54 -        xc.domain_setmaxmem(dominfo.getDomid(), dominfo.getMemoryMaximum())
   58.55 -
   58.56          cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
   58.57                          fd, dominfo.getDomid(),
   58.58                          store_port, console_port, int(is_hvm), pae, apic])
   58.59 @@ -219,7 +230,7 @@ def restore(xd, fd, dominfo = None, paus
   58.60          forkHelper(cmd, fd, handler.handler, True)
   58.61  
   58.62          # We don't want to pass this fd to any other children -- we 
   58.63 -        # might need to recover ths disk space that backs it.
   58.64 +        # might need to recover the disk space that backs it.
   58.65          try:
   58.66              flags = fcntl.fcntl(fd, fcntl.F_GETFD)
   58.67              flags |= fcntl.FD_CLOEXEC
    59.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Sep 06 09:05:26 2007 -0600
    59.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Sep 06 12:05:15 2007 -0600
    59.3 @@ -28,9 +28,9 @@ from xen.xend.XendError import VmError
    59.4  from xen.xend.XendDevices import XendDevices
    59.5  from xen.xend.PrettyPrint import prettyprintstring
    59.6  from xen.xend.XendConstants import DOM_STATE_HALTED
    59.7 +from xen.xend.server.BlktapController import blktap_disk_types
    59.8  from xen.xend.server.netif import randomMAC
    59.9  from xen.util.blkif import blkdev_name_to_number
   59.10 -from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
   59.11  from xen.util import xsconstants
   59.12  
   59.13  log = logging.getLogger("xend.XendConfig")
   59.14 @@ -433,7 +433,8 @@ class XendConfig(dict):
   59.15          self['cpu_time'] = dominfo['cpu_time']/1e9
   59.16          if dominfo.get('ssidref'):
   59.17              ssidref = int(dominfo.get('ssidref'))
   59.18 -            self['security_label'] = XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
   59.19 +            import xen.util.xsm.xsm as security
   59.20 +            self['security_label'] = security.ssidref2security_label(ssidref)
   59.21  
   59.22          self['shutdown_reason'] = dominfo['shutdown_reason']
   59.23  
   59.24 @@ -651,7 +652,6 @@ class XendConfig(dict):
   59.25                  #                     ['ssidref', 196611]]
   59.26                  policy = ""
   59.27                  label = ""
   59.28 -                policytype = xsconstants.ACM_POLICY_ID
   59.29                  for idx in range(0, len(secinfo)):
   59.30                      if secinfo[idx][0] == "access_control":
   59.31                          for aidx in range(1, len(secinfo[idx])):
   59.32 @@ -659,9 +659,10 @@ class XendConfig(dict):
   59.33                                  policy = secinfo[idx][aidx][1]
   59.34                              if secinfo[idx][aidx][0] == "label":
   59.35                                  label  = secinfo[idx][aidx][1]
   59.36 -                if label != "" and policy != "":
   59.37 -                    cfg['security_label'] = "%s:%s:%s" % \
   59.38 -                            (policytype, policy, label)
   59.39 +                import xen.util.xsm.xsm as security
   59.40 +                cfg['security_label'] = \
   59.41 +                    security.set_security_label(policy, label)
   59.42 +                if not sxp.child_value(sxp_cfg, 'security_label'):
   59.43                      del cfg['security']
   59.44  
   59.45          old_state = sxp.child_value(sxp_cfg, 'state')
   59.46 @@ -1084,6 +1085,11 @@ class XendConfig(dict):
   59.47                  else:
   59.48                      dev_info['driver'] = 'paravirtualised'
   59.49  
   59.50 +            if dev_type == 'tap':
   59.51 +                if dev_info['uname'].split(':')[1] not in blktap_disk_types:
   59.52 +                    raise XendConfigError("tap:%s not a valid disk type" %
   59.53 +                                    dev_info['uname'].split(':')[1])
   59.54 +
   59.55              if dev_type == 'vif':
   59.56                  if not dev_info.get('mac'):
   59.57                      dev_info['mac'] = randomMAC()
    60.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 06 09:05:26 2007 -0600
    60.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 06 12:05:15 2007 -0600
    60.3 @@ -36,7 +36,7 @@ from types import StringTypes
    60.4  import xen.lowlevel.xc
    60.5  from xen.util import asserts
    60.6  from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
    60.7 -from xen.util import security
    60.8 +import xen.util.xsm.xsm as security
    60.9  
   60.10  from xen.xend import balloon, sxp, uuid, image, arch, osdep
   60.11  from xen.xend import XendOptions, XendNode, XendConfig
   60.12 @@ -607,6 +607,9 @@ class XendDomainInfo:
   60.13                      _, dev_info = sxprs[dev]
   60.14              else:  # 'vbd' or 'tap'
   60.15                  dev_info = self.getDeviceInfo_vbd(dev)
   60.16 +                # To remove the UUID of the device from refs,
   60.17 +                # deviceClass must be always 'vbd'.
   60.18 +                deviceClass = 'vbd'
   60.19              if dev_info is None:
   60.20                  return rc
   60.21  
   60.22 @@ -981,7 +984,7 @@ class XendDomainInfo:
   60.23              changed = True
   60.24  
   60.25          # Check if the rtc offset has changes
   60.26 -        if vm_details.get("rtc/timeoffset", 0) != self.info["platform"].get("rtc_timeoffset", 0):
   60.27 +        if vm_details.get("rtc/timeoffset", "0") != self.info["platform"].get("rtc_timeoffset", "0"):
   60.28              self.info["platform"]["rtc_timeoffset"] = vm_details.get("rtc/timeoffset", 0)
   60.29              changed = True
   60.30   
   60.31 @@ -1770,7 +1773,8 @@ class XendDomainInfo:
   60.32  
   60.33          self._cleanupVm()
   60.34          if self.dompath is not None:
   60.35 -            xc.domain_destroy_hook(self.domid)
   60.36 +            if self.domid is not None:
   60.37 +                xc.domain_destroy_hook(self.domid)
   60.38              self.destroyDomain()
   60.39  
   60.40          self._cleanup_phantom_devs(paths)
    61.1 --- a/tools/python/xen/xend/XendVDI.py	Thu Sep 06 09:05:26 2007 -0600
    61.2 +++ b/tools/python/xen/xend/XendVDI.py	Thu Sep 06 12:05:15 2007 -0600
    61.3 @@ -23,7 +23,8 @@ import os
    61.4  
    61.5  from xen.util.xmlrpclib2 import stringify
    61.6  from xmlrpclib import dumps, loads
    61.7 -from xen.util import security, xsconstants
    61.8 +from xen.util import xsconstants
    61.9 +import xen.util.xsm.xsm as security
   61.10  from xen.xend.XendError import SecurityError
   61.11  
   61.12  KB = 1024
    62.1 --- a/tools/python/xen/xend/XendXSPolicy.py	Thu Sep 06 09:05:26 2007 -0600
    62.2 +++ b/tools/python/xen/xend/XendXSPolicy.py	Thu Sep 06 12:05:15 2007 -0600
    62.3 @@ -20,7 +20,8 @@ import logging
    62.4  from xen.xend.XendBase import XendBase
    62.5  from xen.xend.XendError import *
    62.6  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    62.7 -from xen.util import xsconstants, security
    62.8 +from xen.util import xsconstants
    62.9 +import xen.util.xsm.xsm as security
   62.10  import base64
   62.11  
   62.12  log = logging.getLogger("xend.XendXSPolicy")
    63.1 --- a/tools/python/xen/xend/XendXSPolicyAdmin.py	Thu Sep 06 09:05:26 2007 -0600
    63.2 +++ b/tools/python/xen/xend/XendXSPolicyAdmin.py	Thu Sep 06 12:05:15 2007 -0600
    63.3 @@ -22,7 +22,8 @@ from xml.dom import minidom, Node
    63.4  
    63.5  from xen.xend.XendLogging import log
    63.6  from xen.xend import uuid
    63.7 -from xen.util import security, xsconstants, dictio, bootloader
    63.8 +from xen.util import xsconstants, dictio, bootloader
    63.9 +import xen.util.xsm.acm.acm as security
   63.10  from xen.util.xspolicy import XSPolicy
   63.11  from xen.util.acmpolicy import ACMPolicy
   63.12  from xen.xend.XendError import SecurityError
    64.1 --- a/tools/python/xen/xend/server/BlktapController.py	Thu Sep 06 09:05:26 2007 -0600
    64.2 +++ b/tools/python/xen/xend/server/BlktapController.py	Thu Sep 06 12:05:15 2007 -0600
    64.3 @@ -7,6 +7,14 @@ from xen.xend.XendLogging import log
    64.4  phantomDev = 0;
    64.5  phantomId = 0;
    64.6  
    64.7 +blktap_disk_types = [
    64.8 +    'aio',
    64.9 +    'sync',
   64.10 +    'vmdk',
   64.11 +    'ram',
   64.12 +    'qcow'
   64.13 +    ]
   64.14 +
   64.15  class BlktapController(BlkifController):
   64.16      def __init__(self, vm):
   64.17          BlkifController.__init__(self, vm)
    65.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Sep 06 09:05:26 2007 -0600
    65.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Sep 06 12:05:15 2007 -0600
    65.3 @@ -20,7 +20,7 @@ import re
    65.4  import string
    65.5  
    65.6  from xen.util import blkif
    65.7 -from xen.util import security
    65.8 +import xen.util.xsm.xsm as security
    65.9  from xen.xend.XendError import VmError
   65.10  from xen.xend.server.DevController import DevController
   65.11  
    66.1 --- a/tools/python/xen/xend/server/netif.py	Thu Sep 06 09:05:26 2007 -0600
    66.2 +++ b/tools/python/xen/xend/server/netif.py	Thu Sep 06 12:05:15 2007 -0600
    66.3 @@ -27,8 +27,8 @@ import re
    66.4  from xen.xend import XendOptions
    66.5  from xen.xend.server.DevController import DevController
    66.6  from xen.xend.XendError import VmError
    66.7 -from xen.util import security
    66.8  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    66.9 +import xen.util.xsm.xsm as security
   66.10  
   66.11  from xen.xend.XendLogging import log
   66.12  
    67.1 --- a/tools/python/xen/xm/addlabel.py	Thu Sep 06 09:05:26 2007 -0600
    67.2 +++ b/tools/python/xen/xm/addlabel.py	Thu Sep 06 12:05:15 2007 -0600
    67.3 @@ -23,7 +23,7 @@ import os
    67.4  import sys
    67.5  
    67.6  from xen.util import dictio
    67.7 -from xen.util import security
    67.8 +import xen.util.xsm.xsm as security
    67.9  from xen.xm.opts import OptionError
   67.10  from xen.util import xsconstants
   67.11  from xen.xm import main as xm_main
    68.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Thu Sep 06 09:05:26 2007 -0600
    68.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Thu Sep 06 12:05:15 2007 -0600
    68.3 @@ -26,11 +26,11 @@ import os, stat
    68.4  import shutil
    68.5  import string
    68.6  import re
    68.7 -from xen.util.security import err
    68.8 -from xen.util.security import policy_dir_prefix, xen_title_re
    68.9 -from xen.util.security import boot_filename, altboot_filename
   68.10 -from xen.util.security import any_title_re, xen_kernel_re, any_module_re
   68.11 -from xen.util.security import empty_line_re, binary_name_re, policy_name_re
   68.12 +from xen.util.xsm.xsm import err
   68.13 +from xen.util.xsm.xsm import policy_dir_prefix, xen_title_re
   68.14 +from xen.util.xsm.xsm import boot_filename, altboot_filename
   68.15 +from xen.util.xsm.xsm import any_title_re, xen_kernel_re, any_module_re
   68.16 +from xen.util.xsm.xsm import empty_line_re, binary_name_re, policy_name_re
   68.17  from xen.util import xsconstants
   68.18  from xen.xm.opts import OptionError
   68.19  from xen.xm import main as xm_main
    69.1 --- a/tools/python/xen/xm/create.py	Thu Sep 06 09:05:26 2007 -0600
    69.2 +++ b/tools/python/xen/xm/create.py	Thu Sep 06 12:05:15 2007 -0600
    69.3 @@ -33,7 +33,7 @@ from xen.xend import osdep
    69.4  import xen.xend.XendClient
    69.5  from xen.xend.XendBootloader import bootloader
    69.6  from xen.util import blkif
    69.7 -from xen.util import security
    69.8 +import xen.util.xsm.xsm as security
    69.9  from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
   69.10  
   69.11  from xen.xm.opts import *
   69.12 @@ -725,7 +725,8 @@ def configure_hvm(config_image, vals):
   69.13      for a in args:
   69.14          if a in vals.__dict__ and vals.__dict__[a] is not None:
   69.15              config_image.append([a, vals.__dict__[a]])
   69.16 -    config_image.append(['vncpasswd', vals.vncpasswd])
   69.17 +    if vals.vncpasswd is not None:
   69.18 +        config_image.append(['vncpasswd', vals.vncpasswd])
   69.19  
   69.20  
   69.21  def make_config(vals):
   69.22 @@ -1220,7 +1221,7 @@ def config_security_check(config, verbos
   69.23              if verbose:
   69.24                  print "   %s: PERMITTED" % (resource)
   69.25  
   69.26 -        except security.ACMError:
   69.27 +        except security.XSMError:
   69.28              print "   %s: DENIED" % (resource)
   69.29              (poltype, res_label, res_policy) = security.get_res_label(resource)
   69.30              if not res_label:
   69.31 @@ -1242,7 +1243,7 @@ def create_security_check(config):
   69.32                  passed = 1
   69.33          else:
   69.34              print "Checking resources: (skipped)"
   69.35 -    except security.ACMError:
   69.36 +    except security.XSMError:
   69.37          sys.exit(-1)
   69.38  
   69.39      return passed
   69.40 @@ -1299,7 +1300,7 @@ def main(argv):
   69.41          map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
   69.42      elif not opts.is_xml:
   69.43          if not create_security_check(config):
   69.44 -            raise security.ACMError(
   69.45 +            raise security.XSMError(
   69.46                  'Security Configuration prevents domain from starting')
   69.47          dom = make_domain(opts, config)
   69.48          
    70.1 --- a/tools/python/xen/xm/dry-run.py	Thu Sep 06 09:05:26 2007 -0600
    70.2 +++ b/tools/python/xen/xm/dry-run.py	Thu Sep 06 12:05:15 2007 -0600
    70.3 @@ -19,7 +19,7 @@
    70.4  """Tests the security settings for a domain and its resources.
    70.5  """
    70.6  import sys
    70.7 -from xen.util import security
    70.8 +import xen.util.xsm.xsm as security
    70.9  from xen.xm import create
   70.10  from xen.xend import sxp
   70.11  from xen.xm.opts import OptionError
    71.1 --- a/tools/python/xen/xm/dumppolicy.py	Thu Sep 06 09:05:26 2007 -0600
    71.2 +++ b/tools/python/xen/xm/dumppolicy.py	Thu Sep 06 12:05:15 2007 -0600
    71.3 @@ -18,7 +18,7 @@
    71.4  """Display currently enforced policy (low-level hypervisor representation).
    71.5  """
    71.6  import sys
    71.7 -from xen.util.security import ACMError, err, dump_policy
    71.8 +from xen.util.xsm.xsm import XSMError, err, dump_policy
    71.9  from xen.xm.opts import OptionError
   71.10  
   71.11  def help():
    72.1 --- a/tools/python/xen/xm/getlabel.py	Thu Sep 06 09:05:26 2007 -0600
    72.2 +++ b/tools/python/xen/xm/getlabel.py	Thu Sep 06 12:05:15 2007 -0600
    72.3 @@ -20,7 +20,7 @@
    72.4  """
    72.5  import sys, os, re
    72.6  from xen.util import dictio
    72.7 -from xen.util import security
    72.8 +import xen.util.xsm.xsm as security
    72.9  from xen.util import xsconstants
   72.10  from xen.xm.opts import OptionError
   72.11  from xen.xm import main as xm_main
   72.12 @@ -62,7 +62,7 @@ def get_resource_label(resource):
   72.13                                      "Please relabel the resource.")
   72.14          print policytype+":"+policy+":"+label
   72.15      else:
   72.16 -        raise security.ACMError("Resource not labeled")
   72.17 +        raise security.XSMError("Resource not labeled")
   72.18  
   72.19  
   72.20  def get_domain_label(configfile):
   72.21 @@ -95,7 +95,7 @@ def get_domain_label(configfile):
   72.22  
   72.23      # send error message if we didn't find anything
   72.24      if acline == "":
   72.25 -        raise security.ACMError("Domain not labeled")
   72.26 +        raise security.XSMError("Domain not labeled")
   72.27  
   72.28      # print out the label
   72.29      (title, data) = acline.split("=", 1)
    73.1 --- a/tools/python/xen/xm/labels.py	Thu Sep 06 09:05:26 2007 -0600
    73.2 +++ b/tools/python/xen/xm/labels.py	Thu Sep 06 12:05:15 2007 -0600
    73.3 @@ -21,8 +21,8 @@
    73.4  import sys
    73.5  import traceback
    73.6  import string
    73.7 -from xen.util.security import ACMError, err, list_labels, active_policy
    73.8 -from xen.util.security import vm_label_re, res_label_re, all_label_re
    73.9 +from xen.util.xsm.xsm import XSMError, err, list_labels, active_policy
   73.10 +from xen.util.xsm.xsm import vm_label_re, res_label_re, all_label_re
   73.11  from xen.xm.opts import OptionError
   73.12  from xen.util.acmpolicy import ACMPolicy
   73.13  from xen.util import xsconstants
   73.14 @@ -78,7 +78,7 @@ def labels(policy, ptype):
   73.15          for label in labels:
   73.16              print label
   73.17  
   73.18 -    except ACMError:
   73.19 +    except XSMError:
   73.20          sys.exit(-1)
   73.21      except:
   73.22          traceback.print_exc(limit = 1)
    74.1 --- a/tools/python/xen/xm/loadpolicy.py	Thu Sep 06 09:05:26 2007 -0600
    74.2 +++ b/tools/python/xen/xm/loadpolicy.py	Thu Sep 06 12:05:15 2007 -0600
    74.3 @@ -20,7 +20,7 @@
    74.4  """
    74.5  import sys
    74.6  import traceback
    74.7 -from xen.util.security import ACMError, err, load_policy
    74.8 +from xen.util.xsm.xsm import XSMError, err, load_policy
    74.9  from xen.xm.opts import OptionError
   74.10  from xen.xm import main as xm_main
   74.11  from xen.util import xsconstants
    75.1 --- a/tools/python/xen/xm/main.py	Thu Sep 06 09:05:26 2007 -0600
    75.2 +++ b/tools/python/xen/xm/main.py	Thu Sep 06 12:05:15 2007 -0600
    75.3 @@ -49,7 +49,8 @@ from xen.xend.XendConstants import *
    75.4  from xen.xm.opts import OptionError, Opts, wrap, set_true
    75.5  from xen.xm import console
    75.6  from xen.util.xmlrpcclient import ServerProxy
    75.7 -from xen.util.security import ACMError
    75.8 +import xen.util.xsm.xsm as security
    75.9 +from xen.util.xsm.xsm import XSMError
   75.10  from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
   75.11  
   75.12  import XenAPI
   75.13 @@ -872,12 +873,7 @@ def parse_doms_info(info):
   75.14          }
   75.15  
   75.16      security_label = get_info('security_label', str, '')
   75.17 -    tmp = security_label.split(":")
   75.18 -    if len(tmp) != 3:
   75.19 -        seclabel = ""
   75.20 -    else:
   75.21 -        seclabel = security_label
   75.22 -    parsed_info['seclabel'] = seclabel
   75.23 +    parsed_info['seclabel'] = security.parse_security_label(security_label)
   75.24  
   75.25      if serverType == SERVER_XEN_API:
   75.26          parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
   75.27 @@ -935,14 +931,14 @@ def xm_brief_list(doms):
   75.28          print format % d
   75.29  
   75.30  def xm_label_list(doms):
   75.31 -    print '%-32s %5s %5s %5s %10s %9s %-8s' % \
   75.32 +    print '%-40s %3s %5s %5s %10s %9s %-10s' % \
   75.33            ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
   75.34 -    
   75.35 +
   75.36      output = []
   75.37 -    format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
   75.38 -             '%(cpu_time)8.1f %(seclabel)9s'
   75.39 +    format = '%(name)-40s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
   75.40 +             '%(cpu_time)8.1f %(seclabel)10s'
   75.41  
   75.42 -    from xen.util import security
   75.43 +    import xen.util.xsm.xsm as security
   75.44          
   75.45      for dom in doms:
   75.46          d = parse_doms_info(dom)
   75.47 @@ -2580,12 +2576,12 @@ def _run_cmd(cmd, cmd_name, args):
   75.48          print e.usage
   75.49      except XenAPIUnsupportedException, e:
   75.50          err(str(e))
   75.51 -    except ACMError, e:
   75.52 +    except XSMError, e:
   75.53          err(str(e))
   75.54      except Exception, e:
   75.55          if serverType != SERVER_XEN_API:
   75.56 -           from xen.util import security
   75.57 -           if isinstance(e, security.ACMError):
   75.58 +           import xen.util.xsm.xsm as security
   75.59 +           if isinstance(e, security.XSMError):
   75.60                 err(str(e))
   75.61                 return False, 1
   75.62          print "Unexpected error:", sys.exc_info()[0]
    76.1 --- a/tools/python/xen/xm/makepolicy.py	Thu Sep 06 09:05:26 2007 -0600
    76.2 +++ b/tools/python/xen/xm/makepolicy.py	Thu Sep 06 12:05:15 2007 -0600
    76.3 @@ -19,7 +19,7 @@
    76.4  """
    76.5  import sys
    76.6  import traceback
    76.7 -from xen.util.security import ACMError, err, make_policy
    76.8 +from xen.util.xsm.xsm import ACMError, err, make_policy
    76.9  from xen.util import xsconstants
   76.10  from xen.xm.opts import OptionError
   76.11  from xen.xm import main as xm_main
    77.1 --- a/tools/python/xen/xm/resources.py	Thu Sep 06 09:05:26 2007 -0600
    77.2 +++ b/tools/python/xen/xm/resources.py	Thu Sep 06 12:05:15 2007 -0600
    77.3 @@ -20,7 +20,7 @@
    77.4  """
    77.5  import sys
    77.6  from xen.util import dictio
    77.7 -from xen.util import security
    77.8 +import xen.util.xsm.xsm as security
    77.9  from xen.util import xsconstants
   77.10  from xen.xm.opts import OptionError
   77.11  from xen.xm import main as xm_main
    78.1 --- a/tools/python/xen/xm/rmlabel.py	Thu Sep 06 09:05:26 2007 -0600
    78.2 +++ b/tools/python/xen/xm/rmlabel.py	Thu Sep 06 12:05:15 2007 -0600
    78.3 @@ -20,7 +20,7 @@
    78.4  """
    78.5  import sys, os, re
    78.6  from xen.util import dictio
    78.7 -from xen.util import security
    78.8 +import xen.util.xsm.xsm as security
    78.9  from xen.xm.opts import OptionError
   78.10  from xen.xm import main as xm_main
   78.11  from xen.xm.main import server
   78.12 @@ -108,7 +108,7 @@ def rm_domain_label(configfile):
   78.13  
   78.14      # send error message if we didn't find anything to remove
   78.15      if not removed:
   78.16 -        raise security.ACMError('Domain not labeled')
   78.17 +        raise security.XSMError('Domain not labeled')
   78.18  
   78.19      # write the data back out to the file
   78.20      fd = open(fil, "wb")
    79.1 --- a/tools/python/xen/xm/setpolicy.py	Thu Sep 06 09:05:26 2007 -0600
    79.2 +++ b/tools/python/xen/xm/setpolicy.py	Thu Sep 06 12:05:15 2007 -0600
    79.3 @@ -26,7 +26,7 @@ import string
    79.4  from xen.util import xsconstants
    79.5  from xen.util.acmpolicy import ACMPolicy
    79.6  from xen.xm.opts import OptionError
    79.7 -from xen.util.security import policy_dir_prefix
    79.8 +from xen.util.xsm.acm.acm import policy_dir_prefix
    79.9  from xen.xm import main as xm_main
   79.10  from xen.xm.main import server
   79.11  
    80.1 --- a/tools/security/secpol_tool.c	Thu Sep 06 09:05:26 2007 -0600
    80.2 +++ b/tools/security/secpol_tool.c	Thu Sep 06 12:05:15 2007 -0600
    80.3 @@ -34,8 +34,8 @@
    80.4  #include <string.h>
    80.5  #include <netinet/in.h>
    80.6  #include <stdint.h>
    80.7 -#include <xen/acm.h>
    80.8 -#include <xen/acm_ops.h>
    80.9 +#include <xen/xsm/acm.h>
   80.10 +#include <xen/xsm/acm_ops.h>
   80.11  
   80.12  #include <xenctrl.h>
   80.13  
    81.1 --- a/tools/security/secpol_xml2bin.c	Thu Sep 06 09:05:26 2007 -0600
    81.2 +++ b/tools/security/secpol_xml2bin.c	Thu Sep 06 12:05:15 2007 -0600
    81.3 @@ -22,6 +22,7 @@
    81.4   *
    81.5   * indent -i4 -kr -nut
    81.6   */
    81.7 +
    81.8  #include <stdio.h>
    81.9  #include <stdlib.h>
   81.10  #include <string.h>
   81.11 @@ -38,7 +39,7 @@
   81.12  #include <libxml/tree.h>
   81.13  #include <libxml/xmlreader.h>
   81.14  #include <stdint.h>
   81.15 -#include <xen/acm.h>
   81.16 +#include <xen/xsm/acm.h>
   81.17  
   81.18  #include "secpol_xml2bin.h"
   81.19  
    82.1 --- a/tools/xm-test/lib/XmTestLib/acm.py	Thu Sep 06 09:05:26 2007 -0600
    82.2 +++ b/tools/xm-test/lib/XmTestLib/acm.py	Thu Sep 06 12:05:15 2007 -0600
    82.3 @@ -18,7 +18,7 @@
    82.4  
    82.5  """
    82.6  from Test import *
    82.7 -from xen.util import security
    82.8 +import xen.util.xsm.xsm as security
    82.9  from xen.xm.main import server
   82.10  from xen.util import xsconstants
   82.11  import re
    83.1 --- a/tools/xm-test/tests/security-acm/01_security-acm_basic.py	Thu Sep 06 09:05:26 2007 -0600
    83.2 +++ b/tools/xm-test/tests/security-acm/01_security-acm_basic.py	Thu Sep 06 12:05:15 2007 -0600
    83.3 @@ -14,7 +14,7 @@
    83.4  # - resources
    83.5  
    83.6  from XmTestLib import *
    83.7 -from xen.util import security
    83.8 +import xen.util.xsm.xsm as security
    83.9  from xen.util import xsconstants
   83.10  import commands
   83.11  import os
    84.1 --- a/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py	Thu Sep 06 09:05:26 2007 -0600
    84.2 +++ b/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py	Thu Sep 06 12:05:15 2007 -0600
    84.3 @@ -9,7 +9,8 @@ from XmTestLib import xapi
    84.4  from XmTestLib.XenAPIDomain import XmTestAPIDomain
    84.5  from XmTestLib import *
    84.6  from xen.xend import XendAPIConstants
    84.7 -from xen.util import acmpolicy, security, xsconstants
    84.8 +import xen.util.xsm.xsm as security
    84.9 +from xen.util import acmpolicy, xsconstants
   84.10  from xen.util.acmpolicy import ACMPolicy
   84.11  from xen.xend.XendDomain import DOM0_UUID
   84.12  from XmTestLib.acm import *
    85.1 --- a/tools/xm-test/tests/security-acm/08_security-acm_xapi.py	Thu Sep 06 09:05:26 2007 -0600
    85.2 +++ b/tools/xm-test/tests/security-acm/08_security-acm_xapi.py	Thu Sep 06 12:05:15 2007 -0600
    85.3 @@ -9,7 +9,8 @@ from XmTestLib import xapi
    85.4  from XmTestLib.XenAPIDomain import XmTestAPIDomain
    85.5  from XmTestLib import *
    85.6  from xen.xend import XendAPIConstants
    85.7 -from xen.util import acmpolicy, security, xsconstants
    85.8 +import xen.util.xsm.xsm as security
    85.9 +from xen.util import acmpolicy, xsconstants
   85.10  import commands
   85.11  import os
   85.12  
    86.1 --- a/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py	Thu Sep 06 09:05:26 2007 -0600
    86.2 +++ b/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py	Thu Sep 06 12:05:15 2007 -0600
    86.3 @@ -10,7 +10,8 @@ from XmTestLib.XenAPIDomain import XmTes
    86.4  from XmTestLib.acm import *
    86.5  from XmTestLib import *
    86.6  from xen.xend import XendAPIConstants
    86.7 -from xen.util import security, xsconstants
    86.8 +import xen.util.xsm.xsm as security
    86.9 +from xen.util import xsconstants
   86.10  from xen.util.acmpolicy import ACMPolicy
   86.11  from xen.xend.XendDomain import DOM0_UUID
   86.12  import base64
    87.1 --- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h	Thu Sep 06 09:05:26 2007 -0600
    87.2 +++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h	Thu Sep 06 12:05:15 2007 -0600
    87.3 @@ -108,12 +108,21 @@ extern char *kasprintf(gfp_t gfp, const 
    87.4  #endif
    87.5  
    87.6  #if defined(_LINUX_NETDEVICE_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
    87.7 -#define netif_tx_lock_bh(dev) (spin_lock_bh(&(dev)->xmit_lock))
    87.8 -#define netif_tx_unlock_bh(dev) (spin_unlock_bh(&(dev)->xmit_lock))
    87.9 +#define netif_tx_lock_bh(dev) spin_lock_bh(&(dev)->xmit_lock)
   87.10 +#define netif_tx_unlock_bh(dev) spin_unlock_bh(&(dev)->xmit_lock)
   87.11  #endif
   87.12  
   87.13  #if defined(__LINUX_SEQLOCK_H) && !defined(DEFINE_SEQLOCK)
   87.14  #define DEFINE_SEQLOCK(x) seqlock_t x = SEQLOCK_UNLOCKED
   87.15  #endif
   87.16  
   87.17 +/* Bug in RHEL4-U3: rw_lock_t is mistakenly defined in DEFINE_RWLOCK() macro */
   87.18 +#if defined(__LINUX_SPINLOCK_H) && defined(DEFINE_RWLOCK)
   87.19 +#define rw_lock_t rwlock_t
   87.20  #endif
   87.21 +
   87.22 +#if defined(__LINUX_SPINLOCK_H) && !defined(DEFINE_RWLOCK)
   87.23 +#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
   87.24 +#endif
   87.25 +
   87.26 +#endif
    88.1 --- a/xen/Makefile	Thu Sep 06 09:05:26 2007 -0600
    88.2 +++ b/xen/Makefile	Thu Sep 06 12:05:15 2007 -0600
    88.3 @@ -1,7 +1,7 @@
    88.4  # This is the correct place to edit the build version.
    88.5  # All other places this is stored (eg. compile.h) should be autogenerated.
    88.6  export XEN_VERSION       = 3
    88.7 -export XEN_SUBVERSION    = 0
    88.8 +export XEN_SUBVERSION    = 2
    88.9  export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
   88.10  export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
   88.11  -include xen-version
   88.12 @@ -55,7 +55,7 @@ build install debug clean distclean csco
   88.13  	$(MAKE) -f $(BASEDIR)/Rules.mk -C include clean
   88.14  	$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
   88.15  	$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
   88.16 -	$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
   88.17 +	$(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
   88.18  	$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
   88.19  	rm -f include/asm *.o $(TARGET)* *~ core
   88.20  	rm -f include/asm-*/asm-offsets.h
   88.21 @@ -122,7 +122,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
   88.22  build-headers:
   88.23  	$(MAKE) -C include/public/foreign
   88.24  
   88.25 -SUBDIRS = acm arch/$(TARGET_ARCH) common drivers 
   88.26 +SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers
   88.27  define all_sources
   88.28      ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
   88.29        find include -name 'asm-*' -prune -o -name '*.h' -print; \
    89.1 --- a/xen/Rules.mk	Thu Sep 06 09:05:26 2007 -0600
    89.2 +++ b/xen/Rules.mk	Thu Sep 06 12:05:15 2007 -0600
    89.3 @@ -52,11 +52,14 @@ HDRS  := $(filter-out %/asm-offsets.h,$(
    89.4  # Note that link order matters!
    89.5  ALL_OBJS-y               += $(BASEDIR)/common/built_in.o
    89.6  ALL_OBJS-y               += $(BASEDIR)/drivers/built_in.o
    89.7 -ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
    89.8 +ALL_OBJS-y               += $(BASEDIR)/xsm/built_in.o
    89.9  ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
   89.10  
   89.11  CFLAGS-y                += -g -D__XEN__
   89.12 -CFLAGS-$(ACM_SECURITY)  += -DACM_SECURITY
   89.13 +CFLAGS-$(XSM_ENABLE)    += -DXSM_ENABLE
   89.14 +CFLAGS-$(FLASK_ENABLE)  += -DFLASK_ENABLE -DXSM_MAGIC=0xf97cff8c
   89.15 +CFLAGS-$(FLASK_ENABLE)  += -DFLASK_DEVELOP -DFLASK_BOOTPARAM -DFLASK_AVC_STATS
   89.16 +CFLAGS-$(ACM_SECURITY)  += -DACM_SECURITY -DXSM_MAGIC=0xbcde0100
   89.17  CFLAGS-$(verbose)       += -DVERBOSE
   89.18  CFLAGS-$(crash_debug)   += -DCRASH_DEBUG
   89.19  CFLAGS-$(perfc)         += -DPERF_COUNTERS
    90.1 --- a/xen/acm/Makefile	Thu Sep 06 09:05:26 2007 -0600
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,5 +0,0 @@
    90.4 -obj-y += acm_core.o 
    90.5 -obj-y += acm_policy.o
    90.6 -obj-y += acm_simple_type_enforcement_hooks.o
    90.7 -obj-y += acm_chinesewall_hooks.o
    90.8 -obj-y += acm_null_hooks.o
    91.1 --- a/xen/acm/acm_chinesewall_hooks.c	Thu Sep 06 09:05:26 2007 -0600
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,724 +0,0 @@
    91.4 -/****************************************************************
    91.5 - * acm_chinesewall_hooks.c
    91.6 - * 
    91.7 - * Copyright (C) 2005 IBM Corporation
    91.8 - *
    91.9 - * Author:
   91.10 - * Reiner Sailer <sailer@watson.ibm.com>
   91.11 - *
   91.12 - * Contributions:
   91.13 - * Stefan Berger <stefanb@watson.ibm.com>
   91.14 - *
   91.15 - * This program is free software; you can redistribute it and/or
   91.16 - * modify it under the terms of the GNU General Public License as
   91.17 - * published by the Free Software Foundation, version 2 of the
   91.18 - * License.
   91.19 - *
   91.20 - * sHype Chinese Wall Policy for Xen
   91.21 - *    This code implements the hooks that are called
   91.22 - *    throughout Xen operations and decides authorization
   91.23 - *    based on domain types and Chinese Wall conflict type 
   91.24 - *    sets. The CHWALL policy decides if a new domain can be started
   91.25 - *    based on the types of running domains and the type of the
   91.26 - *    new domain to be started. If the new domain's type is in
   91.27 - *    conflict with types of running domains, then this new domain
   91.28 - *    is not allowed to be created. A domain can have multiple types,
   91.29 - *    in which case all types of a new domain must be conflict-free
   91.30 - *    with all types of already running domains.
   91.31 - *
   91.32 - * indent -i4 -kr -nut
   91.33 - *
   91.34 - */
   91.35 -
   91.36 -#include <xen/config.h>
   91.37 -#include <xen/errno.h>
   91.38 -#include <xen/types.h>
   91.39 -#include <xen/lib.h>
   91.40 -#include <xen/delay.h>
   91.41 -#include <xen/sched.h>
   91.42 -#include <public/acm.h>
   91.43 -#include <asm/atomic.h>
   91.44 -#include <acm/acm_core.h>
   91.45 -#include <acm/acm_hooks.h>
   91.46 -#include <acm/acm_endian.h>
   91.47 -#include <acm/acm_core.h>
   91.48 -
   91.49 -ssidref_t dom0_chwall_ssidref = 0x0001;
   91.50 -
   91.51 -/* local cache structures for chinese wall policy */
   91.52 -struct chwall_binary_policy chwall_bin_pol;
   91.53 -
   91.54 -/*
   91.55 - * Initializing chinese wall policy (will be filled by policy partition
   91.56 - * using setpolicy command)
   91.57 - */
   91.58 -int acm_init_chwall_policy(void)
   91.59 -{
   91.60 -    /* minimal startup policy; policy write-locked already */
   91.61 -    chwall_bin_pol.max_types = 1;
   91.62 -    chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref;
   91.63 -    chwall_bin_pol.max_conflictsets = 1;
   91.64 -    chwall_bin_pol.ssidrefs =
   91.65 -        (domaintype_t *) xmalloc_array(domaintype_t,
   91.66 -                                       chwall_bin_pol.max_ssidrefs *
   91.67 -                                       chwall_bin_pol.max_types);
   91.68 -    chwall_bin_pol.conflict_sets =
   91.69 -        (domaintype_t *) xmalloc_array(domaintype_t,
   91.70 -                                       chwall_bin_pol.max_conflictsets *
   91.71 -                                       chwall_bin_pol.max_types);
   91.72 -    chwall_bin_pol.running_types =
   91.73 -        (domaintype_t *) xmalloc_array(domaintype_t,
   91.74 -                                       chwall_bin_pol.max_types);
   91.75 -    chwall_bin_pol.conflict_aggregate_set =
   91.76 -        (domaintype_t *) xmalloc_array(domaintype_t,
   91.77 -                                       chwall_bin_pol.max_types);
   91.78 -
   91.79 -    if ( (chwall_bin_pol.conflict_sets == NULL)
   91.80 -        || (chwall_bin_pol.running_types == NULL)
   91.81 -        || (chwall_bin_pol.ssidrefs == NULL)
   91.82 -        || (chwall_bin_pol.conflict_aggregate_set == NULL) )
   91.83 -        return ACM_INIT_SSID_ERROR;
   91.84 -
   91.85 -    /* initialize state */
   91.86 -    memset((void *) chwall_bin_pol.ssidrefs, 0,
   91.87 -           chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types *
   91.88 -           sizeof(domaintype_t));
   91.89 -    memset((void *) chwall_bin_pol.conflict_sets, 0,
   91.90 -           chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types *
   91.91 -           sizeof(domaintype_t));
   91.92 -    memset((void *) chwall_bin_pol.running_types, 0,
   91.93 -           chwall_bin_pol.max_types * sizeof(domaintype_t));
   91.94 -    memset((void *) chwall_bin_pol.conflict_aggregate_set, 0,
   91.95 -           chwall_bin_pol.max_types * sizeof(domaintype_t));
   91.96 -    return ACM_OK;
   91.97 -}
   91.98 -
   91.99 -
  91.100 -static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
  91.101 -{
  91.102 -    struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
  91.103 -    traceprintk("%s.\n", __func__);
  91.104 -
  91.105 -    if ( chwall_ssidp == NULL )
  91.106 -        return ACM_INIT_SSID_ERROR;
  91.107 -
  91.108 -    chwall_ssidp->chwall_ssidref =
  91.109 -        GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  91.110 -
  91.111 -    if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
  91.112 -    {
  91.113 -        printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset "
  91.114 -                "(0).\n",
  91.115 -                __func__, chwall_ssidp->chwall_ssidref);
  91.116 -        xfree(chwall_ssidp);
  91.117 -        return ACM_INIT_SSID_ERROR;
  91.118 -    }
  91.119 -    (*chwall_ssid) = chwall_ssidp;
  91.120 -    printkd("%s: determined chwall_ssidref to %x.\n",
  91.121 -            __func__, chwall_ssidp->chwall_ssidref);
  91.122 -    return ACM_OK;
  91.123 -}
  91.124 -
  91.125 -
  91.126 -static void chwall_free_domain_ssid(void *chwall_ssid)
  91.127 -{
  91.128 -    xfree(chwall_ssid);
  91.129 -    return;
  91.130 -}
  91.131 -
  91.132 -
  91.133 -/* dump chinese wall cache; policy read-locked already */
  91.134 -static int chwall_dump_policy(u8 * buf, u32 buf_size)
  91.135 -{
  91.136 -    struct acm_chwall_policy_buffer *chwall_buf =
  91.137 -        (struct acm_chwall_policy_buffer *) buf;
  91.138 -    int ret = 0;
  91.139 -
  91.140 -    if ( buf_size < sizeof(struct acm_chwall_policy_buffer) )
  91.141 -        return -EINVAL;
  91.142 -
  91.143 -    chwall_buf->chwall_max_types = cpu_to_be32(chwall_bin_pol.max_types);
  91.144 -    chwall_buf->chwall_max_ssidrefs = cpu_to_be32(chwall_bin_pol.max_ssidrefs);
  91.145 -    chwall_buf->policy_code = cpu_to_be32(ACM_CHINESE_WALL_POLICY);
  91.146 -    chwall_buf->chwall_ssid_offset =
  91.147 -        cpu_to_be32(sizeof(struct acm_chwall_policy_buffer));
  91.148 -    chwall_buf->chwall_max_conflictsets =
  91.149 -        cpu_to_be32(chwall_bin_pol.max_conflictsets);
  91.150 -    chwall_buf->chwall_conflict_sets_offset =
  91.151 -        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_ssid_offset) +
  91.152 -              sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs *
  91.153 -              chwall_bin_pol.max_types);
  91.154 -    chwall_buf->chwall_running_types_offset =
  91.155 -        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_conflict_sets_offset) +
  91.156 -              sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
  91.157 -              chwall_bin_pol.max_types);
  91.158 -    chwall_buf->chwall_conflict_aggregate_offset =
  91.159 -        cpu_to_be32(be32_to_cpu(chwall_buf->chwall_running_types_offset) +
  91.160 -              sizeof(domaintype_t) * chwall_bin_pol.max_types);
  91.161 -
  91.162 -    ret = be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset) +
  91.163 -        sizeof(domaintype_t) * chwall_bin_pol.max_types;
  91.164 -
  91.165 -    ret = (ret + 7) & ~7;
  91.166 -
  91.167 -    if ( buf_size < ret )
  91.168 -        return -EINVAL;
  91.169 -
  91.170 -    /* now copy buffers over */
  91.171 -    arrcpy16((u16 *) (buf + be32_to_cpu(chwall_buf->chwall_ssid_offset)),
  91.172 -             chwall_bin_pol.ssidrefs,
  91.173 -             chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
  91.174 -
  91.175 -    arrcpy16((u16 *) (buf +
  91.176 -                      be32_to_cpu(chwall_buf->chwall_conflict_sets_offset)),
  91.177 -             chwall_bin_pol.conflict_sets,
  91.178 -             chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
  91.179 -
  91.180 -    arrcpy16((u16 *) (buf +
  91.181 -                      be32_to_cpu(chwall_buf->chwall_running_types_offset)),
  91.182 -             chwall_bin_pol.running_types, chwall_bin_pol.max_types);
  91.183 -
  91.184 -    arrcpy16((u16 *) (buf +
  91.185 -                      be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset)),
  91.186 -             chwall_bin_pol.conflict_aggregate_set,
  91.187 -             chwall_bin_pol.max_types);
  91.188 -    return ret;
  91.189 -}
  91.190 -
  91.191 -/*
  91.192 - * Adapt security state (running_types and conflict_aggregate_set) to all
  91.193 - * running domains; chwall_init_state is called when a policy is changed
  91.194 - * to bring the security information into a consistent state and to detect
  91.195 - * violations (return != 0) from a security point of view, we simulate
  91.196 - * that all running domains are re-started
  91.197 - */
  91.198 -static int
  91.199 -chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
  91.200 -                  domaintype_t * ssidrefs,
  91.201 -                  domaintype_t * conflict_sets,
  91.202 -                  domaintype_t * running_types,
  91.203 -                  domaintype_t * conflict_aggregate_set,
  91.204 -                  struct acm_sized_buffer *errors /* may be NULL */)
  91.205 -{
  91.206 -    int violation = 0, i, j;
  91.207 -    struct chwall_ssid *chwall_ssid;
  91.208 -    ssidref_t chwall_ssidref;
  91.209 -    struct acm_ssid_domain *rawssid;
  91.210 -
  91.211 -    read_lock(&ssid_list_rwlock);
  91.212 -
  91.213 -    /* go through all domains and adjust policy as if this domain was
  91.214 -     * started now
  91.215 -     */
  91.216 -    for_each_acmssid( rawssid )
  91.217 -    {
  91.218 -        chwall_ssid =
  91.219 -            GET_SSIDP(ACM_CHINESE_WALL_POLICY, rawssid);
  91.220 -        chwall_ssidref = chwall_ssid->chwall_ssidref;
  91.221 -        traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
  91.222 -                    __func__, d->domain_id, chwall_ssidref);
  91.223 -        /* a) adjust types ref-count for running domains */
  91.224 -        for ( i = 0; i < chwall_buf->chwall_max_types; i++ )
  91.225 -            running_types[i] +=
  91.226 -                ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i];
  91.227 -
  91.228 -        /* b) check for conflict */
  91.229 -        for ( i = 0; i < chwall_buf->chwall_max_types; i++ )
  91.230 -            if ( conflict_aggregate_set[i] &&
  91.231 -                 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i] )
  91.232 -            {
  91.233 -                printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
  91.234 -                       __func__, i);
  91.235 -                violation = 1;
  91.236 -
  91.237 -                acm_array_append_tuple(errors, ACM_CHWALL_CONFLICT, i);
  91.238 -
  91.239 -                goto out;
  91.240 -            }
  91.241 -
  91.242 -        /* set violation and break out of the loop */
  91.243 -        /* c) adapt conflict aggregate set for this domain
  91.244 -         *    (notice conflicts)
  91.245 -         */
  91.246 -        for ( i = 0; i < chwall_buf->chwall_max_conflictsets; i++ )
  91.247 -        {
  91.248 -            int common = 0;
  91.249 -            /* check if conflict_set_i and ssidref have common types */
  91.250 -            for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
  91.251 -                if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
  91.252 -                     ssidrefs[chwall_ssidref *
  91.253 -                              chwall_buf->chwall_max_types + j] )
  91.254 -                {
  91.255 -                    common = 1;
  91.256 -                    break;
  91.257 -                }
  91.258 -
  91.259 -            if ( common == 0 )
  91.260 -                continue;       /* try next conflict set */
  91.261 -
  91.262 -            /* now add types of the conflict set to conflict_aggregate_set
  91.263 -             * (except types in chwall_ssidref)
  91.264 -             */
  91.265 -            for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
  91.266 -                if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
  91.267 -                     !ssidrefs[chwall_ssidref *
  91.268 -                               chwall_buf->chwall_max_types + j] )
  91.269 -                    conflict_aggregate_set[j]++;
  91.270 -        }
  91.271 -    }
  91.272 - out:
  91.273 -    read_unlock(&ssid_list_rwlock);
  91.274 -    return violation;
  91.275 -    /* returning "violation != 0" means that the currently running set of
  91.276 -     * domains would not be possible if the new policy had been enforced
  91.277 -     * before starting them; for chinese wall, this means that the new
  91.278 -     * policy includes at least one conflict set of which more than one
  91.279 -     * type is currently running
  91.280 -     */
  91.281 -}
  91.282 -
  91.283 -
  91.284 -int
  91.285 -do_chwall_init_state_curr(struct acm_sized_buffer *errors)
  91.286 -{
  91.287 -    struct acm_chwall_policy_buffer chwall_buf =
  91.288 -    {
  91.289 -         /* only these two are important */
  91.290 -         .chwall_max_types        = chwall_bin_pol.max_types,
  91.291 -         .chwall_max_conflictsets = chwall_bin_pol.max_conflictsets,
  91.292 -    };
  91.293 -    /* reset running_types and aggregate set for recalculation */
  91.294 -    memset(chwall_bin_pol.running_types,
  91.295 -           0x0,
  91.296 -           sizeof(domaintype_t) * chwall_bin_pol.max_types);
  91.297 -    memset(chwall_bin_pol.conflict_aggregate_set,
  91.298 -           0x0,
  91.299 -           sizeof(domaintype_t) * chwall_bin_pol.max_types);
  91.300 -    return chwall_init_state(&chwall_buf,
  91.301 -                             chwall_bin_pol.ssidrefs,
  91.302 -                             chwall_bin_pol.conflict_sets,
  91.303 -                             chwall_bin_pol.running_types,
  91.304 -                             chwall_bin_pol.conflict_aggregate_set,
  91.305 -                             errors);
  91.306 -}
  91.307 -
  91.308 -/*
  91.309 - * Attempt to set the policy. This function must be called in test_only
  91.310 - * mode first to only perform checks. A second call then does the
  91.311 - * actual changes.
  91.312 - */
  91.313 -static int _chwall_update_policy(u8 *buf, u32 buf_size, int test_only,
  91.314 -                                 struct acm_sized_buffer *errors)
  91.315 -{
  91.316 -    int rc = -EFAULT;
  91.317 -    /* policy write-locked already */
  91.318 -    struct acm_chwall_policy_buffer *chwall_buf =
  91.319 -        (struct acm_chwall_policy_buffer *) buf;
  91.320 -    void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL,
  91.321 -         *conflict_aggregate_set = NULL;
  91.322 -
  91.323 -    /* 1. allocate new buffers */
  91.324 -    ssids =
  91.325 -        xmalloc_array(domaintype_t,
  91.326 -                      chwall_buf->chwall_max_types *
  91.327 -                      chwall_buf->chwall_max_ssidrefs);
  91.328 -    conflict_sets =
  91.329 -        xmalloc_array(domaintype_t,
  91.330 -                      chwall_buf->chwall_max_conflictsets *
  91.331 -                      chwall_buf->chwall_max_types);
  91.332 -    running_types =
  91.333 -        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
  91.334 -    conflict_aggregate_set =
  91.335 -        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
  91.336 -
  91.337 -    if ( (ssids == NULL) || (conflict_sets == NULL) ||
  91.338 -         (running_types == NULL) || (conflict_aggregate_set == NULL) )
  91.339 -        goto error_free;
  91.340 -
  91.341 -    /* 2. set new policy */
  91.342 -    if ( chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
  91.343 -         chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs >
  91.344 -         buf_size )
  91.345 -        goto error_free;
  91.346 -
  91.347 -    arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
  91.348 -           sizeof(domaintype_t),
  91.349 -           chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
  91.350 -
  91.351 -    if ( chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
  91.352 -         chwall_buf->chwall_max_types *
  91.353 -         chwall_buf->chwall_max_conflictsets > buf_size )
  91.354 -        goto error_free;
  91.355 -
  91.356 -    arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
  91.357 -           sizeof(domaintype_t),
  91.358 -           chwall_buf->chwall_max_types *
  91.359 -           chwall_buf->chwall_max_conflictsets);
  91.360 -
  91.361 -    /* we also use new state buffers since max_types can change */
  91.362 -    memset(running_types, 0,
  91.363 -           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
  91.364 -    memset(conflict_aggregate_set, 0,
  91.365 -           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
  91.366 -
  91.367 -    /* 3. now re-calculate the state for the new policy based on
  91.368 -     *    running domains; this can fail if new policy is conflicting
  91.369 -     *    with running domains
  91.370 -     */
  91.371 -    if ( chwall_init_state(chwall_buf, ssids,
  91.372 -                           conflict_sets, running_types,
  91.373 -                           conflict_aggregate_set,
  91.374 -                           errors))
  91.375 -    {
  91.376 -        printk("%s: New policy conflicts with running domains. Policy load aborted.\n",
  91.377 -               __func__);
  91.378 -        goto error_free;        /* new policy conflicts with running domains */
  91.379 -    }
  91.380 -
  91.381 -    /* if this was only a test run, exit with ACM_OK */
  91.382 -    if ( test_only )
  91.383 -    {
  91.384 -        rc = ACM_OK;
  91.385 -        goto error_free;
  91.386 -    }
  91.387 -
  91.388 -    /* 4. free old policy buffers, replace with new ones */
  91.389 -    chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
  91.390 -    chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
  91.391 -    chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
  91.392 -    xfree(chwall_bin_pol.ssidrefs);
  91.393 -    xfree(chwall_bin_pol.conflict_aggregate_set);
  91.394 -    xfree(chwall_bin_pol.running_types);
  91.395 -    xfree(chwall_bin_pol.conflict_sets);
  91.396 -    chwall_bin_pol.ssidrefs = ssids;
  91.397 -    chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
  91.398 -    chwall_bin_pol.running_types = running_types;
  91.399 -    chwall_bin_pol.conflict_sets = conflict_sets;
  91.400 -
  91.401 -    return ACM_OK;
  91.402 -
  91.403 - error_free:
  91.404 -    if ( !test_only )
  91.405 -        printk("%s: ERROR setting policy.\n", __func__);
  91.406 -
  91.407 -    xfree(ssids);
  91.408 -    xfree(conflict_sets);
  91.409 -    xfree(running_types);
  91.410 -    xfree(conflict_aggregate_set);
  91.411 -    return rc;
  91.412 -}
  91.413 -
  91.414 -/*
  91.415 - * This function MUST be called before the chwall_ste_policy function!
  91.416 - */
  91.417 -static int chwall_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
  91.418 -                              struct acm_sized_buffer *errors)
  91.419 -{
  91.420 -    struct acm_chwall_policy_buffer *chwall_buf =
  91.421 -        (struct acm_chwall_policy_buffer *) buf;
  91.422 -
  91.423 -    if ( buf_size < sizeof(struct acm_chwall_policy_buffer) )
  91.424 -        return -EINVAL;
  91.425 -
  91.426 -    /* rewrite the policy due to endianess */
  91.427 -    chwall_buf->policy_code = be32_to_cpu(chwall_buf->policy_code);
  91.428 -    chwall_buf->policy_version = be32_to_cpu(chwall_buf->policy_version);
  91.429 -    chwall_buf->chwall_max_types =
  91.430 -        be32_to_cpu(chwall_buf->chwall_max_types);
  91.431 -    chwall_buf->chwall_max_ssidrefs =
  91.432 -        be32_to_cpu(chwall_buf->chwall_max_ssidrefs);
  91.433 -    chwall_buf->chwall_max_conflictsets =
  91.434 -        be32_to_cpu(chwall_buf->chwall_max_conflictsets);
  91.435 -    chwall_buf->chwall_ssid_offset =
  91.436 -        be32_to_cpu(chwall_buf->chwall_ssid_offset);
  91.437 -    chwall_buf->chwall_conflict_sets_offset =
  91.438 -        be32_to_cpu(chwall_buf->chwall_conflict_sets_offset);
  91.439 -    chwall_buf->chwall_running_types_offset =
  91.440 -        be32_to_cpu(chwall_buf->chwall_running_types_offset);
  91.441 -    chwall_buf->chwall_conflict_aggregate_offset =
  91.442 -        be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset);
  91.443 -
  91.444 -    /* policy type and version checks */
  91.445 -    if ( (chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
  91.446 -         (chwall_buf->policy_version != ACM_CHWALL_VERSION) )
  91.447 -        return -EINVAL;
  91.448 -
  91.449 -    /* during boot dom0_chwall_ssidref is set */
  91.450 -    if ( is_bootpolicy &&
  91.451 -         (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs) )
  91.452 -        return -EINVAL;
  91.453 -
  91.454 -    return _chwall_update_policy(buf, buf_size, 1, errors);
  91.455 -}
  91.456 -
  91.457 -static int chwall_set_policy(u8 *buf, u32 buf_size)
  91.458 -{
  91.459 -    return _chwall_update_policy(buf, buf_size, 0, NULL);
  91.460 -}
  91.461 -
  91.462 -static int chwall_dump_stats(u8 * buf, u16 len)
  91.463 -{
  91.464 -    /* no stats for Chinese Wall Policy */
  91.465 -    return 0;
  91.466 -}
  91.467 -
  91.468 -static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len)
  91.469 -{
  91.470 -    int i;
  91.471 -
  91.472 -    /* fill in buffer */
  91.473 -    if ( chwall_bin_pol.max_types > len )
  91.474 -        return -EFAULT;
  91.475 -
  91.476 -    if ( ssidref >= chwall_bin_pol.max_ssidrefs )
  91.477 -        return -EFAULT;
  91.478 -
  91.479 -    /* read types for chwall ssidref */
  91.480 -    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
  91.481 -    {
  91.482 -        if ( chwall_bin_pol.
  91.483 -             ssidrefs[ssidref * chwall_bin_pol.max_types + i] )
  91.484 -            buf[i] = 1;
  91.485 -        else
  91.486 -            buf[i] = 0;
  91.487 -    }
  91.488 -    return chwall_bin_pol.max_types;
  91.489 -}
  91.490 -
  91.491 -/***************************
  91.492 - * Authorization functions
  91.493 - ***************************/
  91.494 -
  91.495 -/* -------- DOMAIN OPERATION HOOKS -----------*/
  91.496 -
  91.497 -static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
  91.498 -{
  91.499 -    ssidref_t chwall_ssidref;
  91.500 -    int i, j;
  91.501 -
  91.502 -    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  91.503 -
  91.504 -    if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
  91.505 -    {
  91.506 -        printk("%s: ERROR chwall_ssidref > max(%x).\n",
  91.507 -               __func__, chwall_bin_pol.max_ssidrefs - 1);
  91.508 -        return ACM_ACCESS_DENIED;
  91.509 -    }
  91.510 -
  91.511 -    /* A: chinese wall check for conflicts */
  91.512 -    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
  91.513 -        if ( chwall_bin_pol.conflict_aggregate_set[i] &&
  91.514 -             chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.515 -                                     chwall_bin_pol.max_types + i] )
  91.516 -        {
  91.517 -            printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
  91.518 -            return ACM_ACCESS_DENIED;
  91.519 -        }
  91.520 -
  91.521 -    /* B: chinese wall conflict set adjustment (so that other
  91.522 -     *    other domains simultaneously created are evaluated against
  91.523 -     *    this new set)
  91.524 -     */
  91.525 -    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
  91.526 -    {
  91.527 -        int common = 0;
  91.528 -        /* check if conflict_set_i and ssidref have common types */
  91.529 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.530 -            if ( chwall_bin_pol.
  91.531 -                 conflict_sets[i * chwall_bin_pol.max_types + j]
  91.532 -                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.533 -                                            chwall_bin_pol.max_types + j] )
  91.534 -            {
  91.535 -                common = 1;
  91.536 -                break;
  91.537 -            }
  91.538 -        if ( common == 0 )
  91.539 -            continue;           /* try next conflict set */
  91.540 -        /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  91.541 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.542 -            if ( chwall_bin_pol.
  91.543 -                 conflict_sets[i * chwall_bin_pol.max_types + j]
  91.544 -                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.545 -                                             chwall_bin_pol.max_types + j])
  91.546 -                 chwall_bin_pol.conflict_aggregate_set[j]++;
  91.547 -    }
  91.548 -    return ACM_ACCESS_PERMITTED;
  91.549 -}
  91.550 -
  91.551 -
  91.552 -static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
  91.553 -{
  91.554 -    int i, j;
  91.555 -    ssidref_t chwall_ssidref;
  91.556 -
  91.557 -    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  91.558 -    /* adjust types ref-count for running domains */
  91.559 -    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
  91.560 -        chwall_bin_pol.running_types[i] +=
  91.561 -            chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.562 -                                   chwall_bin_pol.max_types + i];
  91.563 -    if ( domid )
  91.564 -        return;
  91.565 -
  91.566 -    /* Xen does not call pre-create hook for DOM0;
  91.567 -     * to consider type conflicts of any domain with DOM0, we need
  91.568 -     * to adjust the conflict_aggregate for DOM0 here the same way it
  91.569 -     * is done for non-DOM0 domains in the pre-hook */
  91.570 -    printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n",
  91.571 -            __func__, ssidref, chwall_ssidref);
  91.572 -
  91.573 -    /* chinese wall conflict set adjustment (so that other
  91.574 -     *      other domains simultaneously created are evaluated against this new set)*/
  91.575 -    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
  91.576 -    {
  91.577 -        int common = 0;
  91.578 -        /* check if conflict_set_i and ssidref have common types */
  91.579 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.580 -            if ( chwall_bin_pol.
  91.581 -                 conflict_sets[i * chwall_bin_pol.max_types + j]
  91.582 -                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.583 -                                            chwall_bin_pol.max_types + j] )
  91.584 -            {
  91.585 -                common = 1;
  91.586 -                break;
  91.587 -            }
  91.588 -
  91.589 -        if ( common == 0 )
  91.590 -        {
  91.591 -            /* try next conflict set */
  91.592 -            continue;
  91.593 -        }
  91.594 -
  91.595 -        /* now add types of the conflict set to conflict_aggregate_set
  91.596 -           (except types in chwall_ssidref) */
  91.597 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.598 -            if ( chwall_bin_pol.
  91.599 -                 conflict_sets[i * chwall_bin_pol.max_types + j]
  91.600 -                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.601 -                                             chwall_bin_pol.max_types + j] )
  91.602 -                chwall_bin_pol.conflict_aggregate_set[j]++;
  91.603 -    }
  91.604 -    return;
  91.605 -}
  91.606 -
  91.607 -
  91.608 -/*
  91.609 - * To be called when creating a domain. If this call is unsuccessful,
  91.610 - * no state changes have occurred (adjustments of counters etc.). If it
  91.611 - * was successful, state was changed and can be undone using
  91.612 - * chwall_domain_destroy.
  91.613 - */
  91.614 -static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref,
  91.615 -                                domid_t domid)
  91.616 -{
  91.617 -    int rc;
  91.618 -    read_lock(&acm_bin_pol_rwlock);
  91.619 -
  91.620 -    rc = _chwall_pre_domain_create(subject_ssid, ssidref);
  91.621 -    if ( rc == ACM_ACCESS_PERMITTED )
  91.622 -        _chwall_post_domain_create(domid, ssidref);
  91.623 -
  91.624 -    read_unlock(&acm_bin_pol_rwlock);
  91.625 -    return rc;
  91.626 -}
  91.627 -
  91.628 -/*
  91.629 - * This function undoes everything a successful call to
  91.630 - * chwall_domain_create has done.
  91.631 - */
  91.632 -static void chwall_domain_destroy(void *object_ssid, struct domain *d)
  91.633 -{
  91.634 -    int i, j;
  91.635 -    struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
  91.636 -                                                 (struct acm_ssid_domain *)
  91.637 -                                                 object_ssid);
  91.638 -    ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
  91.639 -
  91.640 -    read_lock(&acm_bin_pol_rwlock);
  91.641 -
  91.642 -    /* adjust running types set */
  91.643 -    for ( i = 0; i < chwall_bin_pol.max_types; i++ )
  91.644 -        chwall_bin_pol.running_types[i] -=
  91.645 -            chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.646 -                                   chwall_bin_pol.max_types + i];
  91.647 -
  91.648 -    /* roll-back: re-adjust conflicting types aggregate */
  91.649 -    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
  91.650 -    {
  91.651 -        int common = 0;
  91.652 -        /* check if conflict_set_i and ssidref have common types */
  91.653 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.654 -            if ( chwall_bin_pol.conflict_sets[i * chwall_bin_pol.max_types + j]
  91.655 -                 && chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.656 -                                            chwall_bin_pol.max_types + j])
  91.657 -            {
  91.658 -                common = 1;
  91.659 -                break;
  91.660 -            }
  91.661 -        if ( common == 0 )
  91.662 -        {
  91.663 -            /* try next conflict set, this one does not include
  91.664 -               any type of chwall_ssidref */
  91.665 -            continue;
  91.666 -        }
  91.667 -
  91.668 -        /* now add types of the conflict set to conflict_aggregate_set
  91.669 -           (except types in chwall_ssidref) */
  91.670 -        for ( j = 0; j < chwall_bin_pol.max_types; j++ )
  91.671 -            if ( chwall_bin_pol.
  91.672 -                 conflict_sets[i * chwall_bin_pol.max_types + j]
  91.673 -                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
  91.674 -                                             chwall_bin_pol.max_types + j])
  91.675 -                chwall_bin_pol.conflict_aggregate_set[j]--;
  91.676 -    }
  91.677 -
  91.678 -    read_unlock(&acm_bin_pol_rwlock);
  91.679 -
  91.680 -    return;
  91.681 -}
  91.682 -
  91.683 -
  91.684 -static int chwall_is_default_policy(void)
  91.685 -{
  91.686 -    return ( (chwall_bin_pol.max_types    == 1 ) &&
  91.687 -             (chwall_bin_pol.max_ssidrefs == 2 ) );
  91.688 -}
  91.689 -
  91.690 -struct acm_operations acm_chinesewall_ops = {
  91.691 -    /* policy management services */
  91.692 -    .init_domain_ssid = chwall_init_domain_ssid,
  91.693 -    .free_domain_ssid = chwall_free_domain_ssid,
  91.694 -    .dump_binary_policy = chwall_dump_policy,
  91.695 -    .test_binary_policy = chwall_test_policy,
  91.696 -    .set_binary_policy = chwall_set_policy,
  91.697 -    .dump_statistics = chwall_dump_stats,
  91.698 -    .dump_ssid_types = chwall_dump_ssid_types,
  91.699 -    /* domain management control hooks */
  91.700 -    .domain_create = chwall_domain_create,
  91.701 -    .domain_destroy = chwall_domain_destroy,
  91.702 -    /* event channel control hooks */
  91.703 -    .pre_eventchannel_unbound = NULL,
  91.704 -    .fail_eventchannel_unbound = NULL,
  91.705 -    .pre_eventchannel_interdomain = NULL,
  91.706 -    .fail_eventchannel_interdomain = NULL,
  91.707 -    /* grant table control hooks */
  91.708 -    .pre_grant_map_ref = NULL,
  91.709 -    .fail_grant_map_ref = NULL,
  91.710 -    .pre_grant_setup = NULL,
  91.711 -    .fail_grant_setup = NULL,
  91.712 -    /* generic domain-requested decision hooks */
  91.713 -    .sharing = NULL,
  91.714 -    .authorization = NULL,
  91.715 -
  91.716 -    .is_default_policy = chwall_is_default_policy,
  91.717 -};
  91.718 -
  91.719 -/*
  91.720 - * Local variables:
  91.721 - * mode: C
  91.722 - * c-set-style: "BSD"
  91.723 - * c-basic-offset: 4
  91.724 - * tab-width: 4
  91.725 - * indent-tabs-mode: nil
  91.726 - * End:
  91.727 - */
    92.1 --- a/xen/acm/acm_core.c	Thu Sep 06 09:05:26 2007 -0600
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,392 +0,0 @@
    92.4 -/****************************************************************
    92.5 - * acm_core.c
    92.6 - * 
    92.7 - * Copyright (C) 2005 IBM Corporation
    92.8 - *
    92.9 - * Author:
   92.10 - * Reiner Sailer <sailer@watson.ibm.com>
   92.11 - *
   92.12 - * Contributors:
   92.13 - * Stefan Berger <stefanb@watson.ibm.com>
   92.14 - *
   92.15 - * This program is free software; you can redistribute it and/or
   92.16 - * modify it under the terms of the GNU General Public License as
   92.17 - * published by the Free Software Foundation, version 2 of the
   92.18 - * License.
   92.19 - *
   92.20 - * sHype access control module (ACM)
   92.21 - *       This file handles initialization of the ACM
   92.22 - *       as well as initializing/freeing security 
   92.23 - *       identifiers for domains (it calls on active
   92.24 - *       policy hook functions).
   92.25 - *
   92.26 - */
   92.27 -
   92.28 -#include <xen/config.h>
   92.29 -#include <xen/errno.h>
   92.30 -#include <xen/types.h>
   92.31 -#include <xen/lib.h>
   92.32 -#include <xen/delay.h>
   92.33 -#include <xen/sched.h>
   92.34 -#include <xen/multiboot.h>
   92.35 -#include <acm/acm_hooks.h>
   92.36 -#include <acm/acm_endian.h>
   92.37 -
   92.38 -/* debug: 
   92.39 - *   include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
   92.40 - *   define/undefine this constant to receive / suppress any
   92.41 - *   security hook debug output of sHype
   92.42 - *
   92.43 - *   include/public/acm.h defines a constant ACM_DEBUG
   92.44 - *   define/undefine this constant to receive non-hook-related
   92.45 - *   debug output.
   92.46 - */
   92.47 -
   92.48 -/* function prototypes */
   92.49 -void acm_init_chwall_policy(void);
   92.50 -void acm_init_ste_policy(void);
   92.51 -
   92.52 -extern struct acm_operations acm_chinesewall_ops, 
   92.53 -    acm_simple_type_enforcement_ops, acm_null_ops;
   92.54 -
   92.55 -/* global ACM policy  (now dynamically determined at boot time) */
   92.56 -u16 acm_active_security_policy = ACM_POLICY_UNDEFINED;
   92.57 -
   92.58 -/* global ops structs called by the hooks */
   92.59 -struct acm_operations *acm_primary_ops = NULL;
   92.60 -/* called in hook if-and-only-if primary succeeds */
   92.61 -struct acm_operations *acm_secondary_ops = NULL;
   92.62 -
   92.63 -/* acm global binary policy (points to 'local' primary and secondary policies */
   92.64 -struct acm_binary_policy acm_bin_pol;
   92.65 -/* acm binary policy lock */
   92.66 -DEFINE_RWLOCK(acm_bin_pol_rwlock);
   92.67 -
   92.68 -/* ACM's only accepted policy name during boot */
   92.69 -char polname[80];
   92.70 -char *acm_accepted_boot_policy_name = NULL;
   92.71 -
   92.72 -/* a lits of all chained ssid structures */
   92.73 -LIST_HEAD(ssid_list);
   92.74 -DEFINE_RWLOCK(ssid_list_rwlock);
   92.75 -
   92.76 -static void __init set_dom0_ssidref(const char *val)
   92.77 -{
   92.78 -    /* expected format:
   92.79 -         ssidref=<hex number>:<policy name>
   92.80 -         Policy name must not have a 'space'.
   92.81 -     */
   92.82 -    const char *c;
   92.83 -    int lo, hi;
   92.84 -    int i;
   92.85 -    int dom0_ssidref = simple_strtoull(val, &c, 0);
   92.86 -
   92.87 -    if (!strncmp(&c[0],":ACM:", 5)) {
   92.88 -        lo = dom0_ssidref & 0xffff;
   92.89 -        if (lo < ACM_MAX_NUM_TYPES && lo >= 1)
   92.90 -            dom0_chwall_ssidref = lo;
   92.91 -        hi = dom0_ssidref >> 16;
   92.92 -        if (hi < ACM_MAX_NUM_TYPES && hi >= 1)
   92.93 -            dom0_ste_ssidref = hi;
   92.94 -        for (i = 0; i < sizeof(polname); i++) {
   92.95 -            polname[i] = c[5+i];
   92.96 -            if (polname[i] == '\0' || polname[i] == '\t' ||
   92.97 -                polname[i] == '\n' || polname[i] == ' '  ||
   92.98 -                polname[i] == ':') {
   92.99 -                break;
  92.100 -            }
  92.101 -        }
  92.102 -        polname[i] = 0;
  92.103 -        acm_accepted_boot_policy_name = polname;
  92.104 -    }
  92.105 -}
  92.106 -
  92.107 -custom_param("ssidref", set_dom0_ssidref);
  92.108 -
  92.109 -int
  92.110 -acm_set_policy_reference(u8 *buf, u32 buf_size)
  92.111 -{
  92.112 -    char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer));
  92.113 -    struct acm_policy_reference_buffer *pr = (struct acm_policy_reference_buffer *)buf;
  92.114 -
  92.115 -    if (acm_accepted_boot_policy_name != NULL) {
  92.116 -        if (strcmp(acm_accepted_boot_policy_name, name)) {
  92.117 -            printk("Policy's name '%s' is not the expected one '%s'.\n",
  92.118 -                   name, acm_accepted_boot_policy_name);
  92.119 -            return ACM_ERROR;
  92.120 -        }
  92.121 -    }
  92.122 -
  92.123 -    acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, be32_to_cpu(pr->len));
  92.124 -
  92.125 -    if (!acm_bin_pol.policy_reference_name)
  92.126 -        return -ENOMEM;
  92.127 -    strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len));
  92.128 -
  92.129 -    printk("%s: Activating policy %s\n", __func__,
  92.130 -           acm_bin_pol.policy_reference_name);
  92.131 -    return 0;
  92.132 -}
  92.133 -
  92.134 -int
  92.135 -acm_dump_policy_reference(u8 *buf, u32 buf_size)
  92.136 -{
  92.137 -    struct acm_policy_reference_buffer *pr_buf = (struct acm_policy_reference_buffer *)buf;
  92.138 -    int ret = sizeof(struct acm_policy_reference_buffer) + strlen(acm_bin_pol.policy_reference_name) + 1;
  92.139 -
  92.140 -    ret = (ret + 7) & ~7;
  92.141 -    if (buf_size < ret)
  92.142 -        return -EINVAL;
  92.143 -
  92.144 -    memset(buf, 0, ret);
  92.145 -    pr_buf->len = cpu_to_be32(strlen(acm_bin_pol.policy_reference_name) + 1); /* including stringend '\0' */
  92.146 -    strlcpy((char *)(buf + sizeof(struct acm_policy_reference_buffer)),
  92.147 -            acm_bin_pol.policy_reference_name,
  92.148 -            be32_to_cpu(pr_buf->len));
  92.149 -    return ret;
  92.150 -}
  92.151 -
  92.152 -int
  92.153 -acm_init_binary_policy(u32 policy_code)
  92.154 -{
  92.155 -    int ret = ACM_OK;
  92.156 -
  92.157 -    acm_bin_pol.primary_policy_code = (policy_code & 0x0f);
  92.158 -    acm_bin_pol.secondary_policy_code = (policy_code >> 4) & 0x0f;
  92.159 -
  92.160 -    write_lock(&acm_bin_pol_rwlock);
  92.161 -
  92.162 -    /* set primary policy component */
  92.163 -    switch ((policy_code) & 0x0f)
  92.164 -    {
  92.165 -
  92.166 -    case ACM_CHINESE_WALL_POLICY:
  92.167 -        acm_init_chwall_policy();
  92.168 -        acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
  92.169 -        acm_primary_ops = &acm_chinesewall_ops;
  92.170 -        break;
  92.171 -
  92.172 -    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
  92.173 -        acm_init_ste_policy();
  92.174 -        acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
  92.175 -        acm_primary_ops = &acm_simple_type_enforcement_ops;
  92.176 -        break;
  92.177 -
  92.178 -    case ACM_NULL_POLICY:
  92.179 -        acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
  92.180 -        acm_primary_ops = &acm_null_ops;
  92.181 -        break;
  92.182 -
  92.183 -    default:
  92.184 -        /* Unknown policy not allowed primary */
  92.185 -        ret = -EINVAL;
  92.186 -        goto out;
  92.187 -    }
  92.188 -
  92.189 -    /* secondary policy component part */
  92.190 -    switch ((policy_code) >> 4)
  92.191 -    {
  92.192 -
  92.193 -    case ACM_NULL_POLICY:
  92.194 -        acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
  92.195 -        acm_secondary_ops = &acm_null_ops;
  92.196 -        break;
  92.197 -
  92.198 -    case ACM_CHINESE_WALL_POLICY:
  92.199 -        if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
  92.200 -        {   /* not a valid combination */
  92.201 -            ret = -EINVAL;
  92.202 -            goto out;
  92.203 -        }
  92.204 -        acm_init_chwall_policy();
  92.205 -        acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
  92.206 -        acm_secondary_ops = &acm_chinesewall_ops;
  92.207 -        break;
  92.208 -
  92.209 -    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
  92.210 -        if (acm_bin_pol.primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
  92.211 -        {   /* not a valid combination */
  92.212 -            ret = -EINVAL;
  92.213 -            goto out;
  92.214 -        }
  92.215 -        acm_init_ste_policy();
  92.216 -        acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
  92.217 -        acm_secondary_ops = &acm_simple_type_enforcement_ops;
  92.218 -        break;
  92.219 -
  92.220 -    default:
  92.221 -        ret = -EINVAL;
  92.222 -        goto out;
  92.223 -    }
  92.224 -
  92.225 - out:
  92.226 -    write_unlock(&acm_bin_pol_rwlock);
  92.227 -    return ret;
  92.228 -}
  92.229 -
  92.230 -int
  92.231 -acm_is_policy(char *buf, unsigned long len)
  92.232 -{
  92.233 -    struct acm_policy_buffer *pol;
  92.234 -
  92.235 -    if (buf == NULL || len < sizeof(struct acm_policy_buffer))
  92.236 -        return 0;
  92.237 -
  92.238 -    pol = (struct acm_policy_buffer *)buf;
  92.239 -    return be32_to_cpu(pol->magic) == ACM_MAGIC;
  92.240 -}
  92.241 -
  92.242 -
  92.243 -static int
  92.244 -acm_setup(char *policy_start,
  92.245 -          unsigned long policy_len,
  92.246 -          int is_bootpolicy)
  92.247 -{
  92.248 -    int rc = ACM_OK;
  92.249 -    struct acm_policy_buffer *pol;
  92.250 -
  92.251 -    if (policy_start == NULL || policy_len < sizeof(struct acm_policy_buffer))
  92.252 -        return rc;
  92.253 -
  92.254 -    pol = (struct acm_policy_buffer *)policy_start;
  92.255 -    if (be32_to_cpu(pol->magic) != ACM_MAGIC)
  92.256 -        return rc;
  92.257 -
  92.258 -    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len,
  92.259 -                           is_bootpolicy,
  92.260 -                           NULL, NULL, NULL);
  92.261 -    if (rc == ACM_OK)
  92.262 -    {
  92.263 -        printkd("Policy len  0x%lx, start at %p.\n",policy_len,policy_start);
  92.264 -    }
  92.265 -    else
  92.266 -    {
  92.267 -        printk("Invalid policy.\n");
  92.268 -        /* load default policy later */
  92.269 -        acm_active_security_policy = ACM_POLICY_UNDEFINED;
  92.270 -    }
  92.271 -    return rc;
  92.272 -}
  92.273 -
  92.274 -
  92.275 -int __init
  92.276 -acm_init(char *policy_start,
  92.277 -         unsigned long policy_len)
  92.278 -{
  92.279 -    int ret = ACM_OK;
  92.280 -
  92.281 -    /* first try to load the boot policy (uses its own locks) */
  92.282 -    acm_setup(policy_start, policy_len, 1);
  92.283 -
  92.284 -    /* a user-provided policy may have any name; only matched during boot */
  92.285 -    acm_accepted_boot_policy_name = NULL;
  92.286 -
  92.287 -    if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
  92.288 -    {
  92.289 -        printk("%s: Enforcing %s boot policy.\n", __func__,
  92.290 -               ACM_POLICY_NAME(acm_active_security_policy));
  92.291 -        goto out;
  92.292 -    }
  92.293 -    /* else continue with the minimal hardcoded default startup policy */
  92.294 -    printk("%s: Loading default policy (%s).\n",
  92.295 -           __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
  92.296 -
  92.297 -    /* (re-)set dom-0 ssidref to default */
  92.298 -    dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001;
  92.299 -
  92.300 -    if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
  92.301 -        ret = -EINVAL;
  92.302 -        goto out;
  92.303 -    }
  92.304 -    acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY;
  92.305 -    if (acm_active_security_policy != ACM_NULL_POLICY)
  92.306 -        acm_bin_pol.policy_reference_name = "DEFAULT";
  92.307 -    else
  92.308 -        acm_bin_pol.policy_reference_name = "NULL";
  92.309 -
  92.310 - out:
  92.311 -    if (ret != ACM_OK)
  92.312 -    {
  92.313 -        printk("%s: Error initializing policies.\n", __func__);
  92.314 -        /* here one could imagine a clean panic */
  92.315 -        return -EINVAL;
  92.316 -    }
  92.317 -    return ret;
  92.318 -}
  92.319 -
  92.320 -int acm_init_domain_ssid(struct domain *subj, ssidref_t ssidref)
  92.321 -{
  92.322 -    struct acm_ssid_domain *ssid;
  92.323 -    int ret1, ret2;
  92.324 -    if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
  92.325 -    {
  92.326 -        return ACM_INIT_SSID_ERROR;
  92.327 -    }
  92.328 -
  92.329 -    INIT_LIST_HEAD(&ssid->node);
  92.330 -    ssid->datatype       = ACM_DATATYPE_domain;
  92.331 -    ssid->subject        = subj;
  92.332 -    ssid->domainid       = subj->domain_id;
  92.333 -    ssid->primary_ssid   = NULL;
  92.334 -    ssid->secondary_ssid = NULL;
  92.335 -
  92.336 -    if (acm_active_security_policy != ACM_NULL_POLICY)
  92.337 -        ssid->ssidref = ssidref;
  92.338 -    else
  92.339 -        ssid->ssidref = ACM_DEFAULT_SSID;
  92.340 -
  92.341 -    subj->ssid           = ssid;
  92.342 -    /* now fill in primary and secondary parts; we only get here through hooks */
  92.343 -    if (acm_primary_ops->init_domain_ssid != NULL)
  92.344 -        ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
  92.345 -    else
  92.346 -        ret1 = ACM_OK;
  92.347 -
  92.348 -    if (acm_secondary_ops->init_domain_ssid != NULL)
  92.349 -        ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
  92.350 -    else
  92.351 -        ret2 = ACM_OK;
  92.352 -
  92.353 -    if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
  92.354 -    {
  92.355 -        printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
  92.356 -               __func__, subj->domain_id);
  92.357 -        acm_free_domain_ssid(ssid);
  92.358 -        return ACM_INIT_SSID_ERROR;
  92.359 -    }
  92.360 -
  92.361 -    printkd("%s: assigned domain %x the ssidref=%x.\n",
  92.362 -           __func__, subj->domain_id, ssid->ssidref);
  92.363 -    return ACM_OK;
  92.364 -}
  92.365 -
  92.366 -
  92.367 -void
  92.368 -acm_free_domain_ssid(struct acm_ssid_domain *ssid)
  92.369 -{
  92.370 -    /* domain is already gone, just ssid is left */
  92.371 -    if (ssid == NULL)
  92.372 -        return;
  92.373 -
  92.374 -    ssid->subject = NULL;
  92.375 -    if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
  92.376 -        acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
  92.377 -    ssid->primary_ssid = NULL;
  92.378 -    if (acm_secondary_ops->free_domain_ssid != NULL)
  92.379 -        acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
  92.380 -    ssid->secondary_ssid = NULL;
  92.381 -
  92.382 -    xfree(ssid);
  92.383 -    printkd("%s: Freed individual domain ssid (domain=%02x).\n",
  92.384 -            __func__, id);
  92.385 -}
  92.386 -
  92.387 -/*
  92.388 - * Local variables:
  92.389 - * mode: C
  92.390 - * c-set-style: "BSD"
  92.391 - * c-basic-offset: 4
  92.392 - * tab-width: 4
  92.393 - * indent-tabs-mode: nil
  92.394 - * End:
  92.395 - */
    93.1 --- a/xen/acm/acm_null_hooks.c	Thu Sep 06 09:05:26 2007 -0600
    93.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.3 @@ -1,95 +0,0 @@
    93.4 -/****************************************************************
    93.5 - * acm_null_hooks.c
    93.6 - * 
    93.7 - * Copyright (C) 2005 IBM Corporation
    93.8 - *
    93.9 - * Author:
   93.10 - * Reiner Sailer <sailer@watson.ibm.com>
   93.11 - *
   93.12 - * This program is free software; you can redistribute it and/or
   93.13 - * modify it under the terms of the GNU General Public License as
   93.14 - * published by the Free Software Foundation, version 2 of the
   93.15 - * License.
   93.16 - */
   93.17 -
   93.18 -#include <acm/acm_hooks.h>
   93.19 -
   93.20 -static int
   93.21 -null_init_domain_ssid(void **ssid, ssidref_t ssidref)
   93.22 -{
   93.23 -    return ACM_OK;
   93.24 -}
   93.25 -
   93.26 -static void
   93.27 -null_free_domain_ssid(void *ssid)
   93.28 -{
   93.29 -    return;
   93.30 -}
   93.31 -
   93.32 -static int
   93.33 -null_dump_binary_policy(u8 *buf, u32 buf_size)
   93.34 -{ 
   93.35 -    return 0;
   93.36 -}
   93.37 -
   93.38 -static int
   93.39 -null_test_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
   93.40 -                        struct acm_sized_buffer *errors)
   93.41 -{
   93.42 -    return ACM_OK;
   93.43 -}
   93.44 -
   93.45 -static int
   93.46 -null_set_binary_policy(u8 *buf, u32 buf_size)
   93.47 -{ 
   93.48 -    return ACM_OK;
   93.49 -}
   93.50 - 
   93.51 -static int 
   93.52 -null_dump_stats(u8 *buf, u16 buf_size)
   93.53 -{
   93.54 -    /* no stats for NULL policy */
   93.55 -    return 0;
   93.56 -}
   93.57 -
   93.58 -static int
   93.59 -null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size)
   93.60 -{
   93.61 -    /* no types */
   93.62 -    return 0;
   93.63 -}
   93.64 -
   93.65 -
   93.66 -/* now define the hook structure similarly to LSM */
   93.67 -struct acm_operations acm_null_ops = {
   93.68 -    .init_domain_ssid = null_init_domain_ssid,
   93.69 -    .free_domain_ssid = null_free_domain_ssid,
   93.70 -    .dump_binary_policy = null_dump_binary_policy,
   93.71 -    .test_binary_policy = null_test_binary_policy,
   93.72 -    .set_binary_policy = null_set_binary_policy,
   93.73 -    .dump_statistics = null_dump_stats,
   93.74 -    .dump_ssid_types = null_dump_ssid_types,
   93.75 -    /* domain management control hooks */
   93.76 -    .domain_create = NULL,
   93.77 -    .domain_destroy = NULL,
   93.78 -    /* event channel control hooks */
   93.79 -    .pre_eventchannel_unbound = NULL,
   93.80 -    .fail_eventchannel_unbound = NULL,
   93.81 -    .pre_eventchannel_interdomain = NULL,
   93.82 -    .fail_eventchannel_interdomain = NULL,
   93.83 -    /* grant table control hooks */
   93.84 -    .pre_grant_map_ref = NULL,
   93.85 -    .fail_grant_map_ref = NULL,
   93.86 -    .pre_grant_setup = NULL,
   93.87 -    .fail_grant_setup = NULL
   93.88 -};
   93.89 -
   93.90 -/*
   93.91 - * Local variables:
   93.92 - * mode: C
   93.93 - * c-set-style: "BSD"
   93.94 - * c-basic-offset: 4
   93.95 - * tab-width: 4
   93.96 - * indent-tabs-mode: nil
   93.97 - * End:
   93.98 - */
    94.1 --- a/xen/acm/acm_policy.c	Thu Sep 06 09:05:26 2007 -0600
    94.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.3 @@ -1,876 +0,0 @@
    94.4 -/****************************************************************
    94.5 - * acm_policy.c
    94.6 - * 
    94.7 - * Copyright (C) 2005-2007 IBM Corporation
    94.8 - *
    94.9 - * Author:
   94.10 - * Reiner Sailer <sailer@watson.ibm.com>
   94.11 - *
   94.12 - * Contributors:
   94.13 - * Stefan Berger <stefanb@watson.ibm.com>
   94.14 - *
   94.15 - * This program is free software; you can redistribute it and/or
   94.16 - * modify it under the terms of the GNU General Public License as
   94.17 - * published by the Free Software Foundation, version 2 of the
   94.18 - * License.
   94.19 - *
   94.20 - * sHype access control policy management for Xen.
   94.21 - *       This interface allows policy tools in authorized
   94.22 - *       domains to interact with the Xen access control module
   94.23 - * 
   94.24 - */
   94.25 -
   94.26 -#include <xen/config.h>
   94.27 -#include <xen/errno.h>
   94.28 -#include <xen/types.h>
   94.29 -#include <xen/lib.h>
   94.30 -#include <xen/delay.h>
   94.31 -#include <xen/sched.h>
   94.32 -#include <xen/guest_access.h>
   94.33 -#include <public/xen.h>
   94.34 -#include <acm/acm_core.h>
   94.35 -#include <public/acm_ops.h>
   94.36 -#include <acm/acm_hooks.h>
   94.37 -#include <acm/acm_endian.h>
   94.38 -#include <asm/current.h>
   94.39 -
   94.40 -static int acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels,
   94.41 -                                      struct acm_sized_buffer *errors);
   94.42 -static void acm_doms_change_ssidref(ssidref_t (*translator)
   94.43 -                                   (const struct acm_ssid_domain *,
   94.44 -                                    const struct acm_sized_buffer *),
   94.45 -                                    struct acm_sized_buffer *translation_map);
   94.46 -static void acm_doms_restore_ssidref(void);
   94.47 -static ssidref_t oldssid_to_newssid(const struct acm_ssid_domain *,
   94.48 -                                    const struct acm_sized_buffer *map);
   94.49 -
   94.50 -
   94.51 -int
   94.52 -acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
   94.53 -{
   94.54 -    u8 *policy_buffer = NULL;
   94.55 -    int ret = -EFAULT;
   94.56 -
   94.57 -    if ( buf_size < sizeof(struct acm_policy_buffer) )
   94.58 -        return -EFAULT;
   94.59 -
   94.60 -    /* copy buffer from guest domain */
   94.61 -    if ( (policy_buffer = xmalloc_array(u8, buf_size)) == NULL )
   94.62 -        return -ENOMEM;
   94.63 -
   94.64 -    if ( copy_from_guest(policy_buffer, buf, buf_size) )
   94.65 -    {
   94.66 -        printk("%s: Error copying!\n",__func__);
   94.67 -        goto error_free;
   94.68 -    }
   94.69 -    ret = do_acm_set_policy(policy_buffer, buf_size, 0,
   94.70 -                            NULL, NULL, NULL);
   94.71 -
   94.72 - error_free:
   94.73 -    xfree(policy_buffer);
   94.74 -    return ret;
   94.75 -}
   94.76 -
   94.77 -
   94.78 -/*
   94.79 - * Update the policy of the running system by:
   94.80 - * - deleting ssidrefs that are not in the new policy anymore
   94.81 - *   -> no running domain may use such an ssidref
   94.82 - * - assign new ssidrefs to domains based on their old ssidrefs
   94.83 - *
   94.84 - */
   94.85 -static int
   94.86 -_acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy,
   94.87 -                   struct acm_policy_buffer *pol,
   94.88 -                   struct acm_sized_buffer *deletions,
   94.89 -                   struct acm_sized_buffer *ssidchanges,
   94.90 -                   struct acm_sized_buffer *errors)
   94.91 -{
   94.92 -    uint32_t offset, length;
   94.93 -    static int require_update = 0;
   94.94 -
   94.95 -    write_lock(&acm_bin_pol_rwlock);
   94.96 -
   94.97 -    if (  require_update != 0 &&
   94.98 -        ( deletions == NULL || ssidchanges == NULL ) )
   94.99 -        goto error_lock_free;
  94.100 -
  94.101 -    require_update = 1;
  94.102 -    /*
  94.103 -       first some tests to check compatibility of new policy with
  94.104 -       current state of system/domains
  94.105 -     */
  94.106 -
  94.107 -    /* if ssidrefs are to be deleted, make sure no domain is using them */
  94.108 -    if ( deletions != NULL )
  94.109 -        if ( acm_check_deleted_ssidrefs(deletions, errors) )
  94.110 -            goto error_lock_free;
  94.111 -
  94.112 -    if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) )
  94.113 -        /* assign all running domains new ssidrefs as requested */
  94.114 -        acm_doms_change_ssidref(oldssid_to_newssid, ssidchanges);
  94.115 -
  94.116 -    /* test primary policy data with the new ssidrefs */
  94.117 -    offset = be32_to_cpu(pol->primary_buffer_offset);
  94.118 -    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
  94.119 -
  94.120 -    if ( (offset + length) > buf_size ||
  94.121 -         acm_primary_ops->test_binary_policy(buf + offset, length,
  94.122 -                                             is_bootpolicy,
  94.123 -                                             errors))
  94.124 -        goto error_lock_free;
  94.125 -
  94.126 -    /* test secondary policy data with the new ssidrefs */
  94.127 -    offset = be32_to_cpu(pol->secondary_buffer_offset);
  94.128 -    length = be32_to_cpu(pol->len) - offset;
  94.129 -    if ( (offset + length) > buf_size ||
  94.130 -         acm_secondary_ops->test_binary_policy(buf + offset, length,
  94.131 -                                               is_bootpolicy,
  94.132 -                                               errors))
  94.133 -        goto error_lock_free;
  94.134 -
  94.135 -    /* end of testing --- now real updates */
  94.136 -
  94.137 -    offset = be32_to_cpu(pol->policy_reference_offset);
  94.138 -    length = be32_to_cpu(pol->primary_buffer_offset) - offset;
  94.139 -
  94.140 -    /* set label reference name */
  94.141 -    if ( (offset + length) > buf_size ||
  94.142 -         acm_set_policy_reference(buf + offset, length) )
  94.143 -        goto error_lock_free;
  94.144 -
  94.145 -    /* set primary policy data */
  94.146 -    offset = be32_to_cpu(pol->primary_buffer_offset);
  94.147 -    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
  94.148 -
  94.149 -    if ( acm_primary_ops->set_binary_policy(buf + offset, length) )
  94.150 -        goto error_lock_free;
  94.151 -
  94.152 -    /* set secondary policy data */
  94.153 -    offset = be32_to_cpu(pol->secondary_buffer_offset);
  94.154 -    length = be32_to_cpu(pol->len) - offset;
  94.155 -    if ( acm_secondary_ops->set_binary_policy(buf + offset, length) )
  94.156 -        goto error_lock_free;
  94.157 -
  94.158 -    memcpy(&acm_bin_pol.xml_pol_version,
  94.159 -           &pol->xml_pol_version,
  94.160 -           sizeof(acm_bin_pol.xml_pol_version));
  94.161 -
  94.162 -    if ( acm_primary_ops->is_default_policy() &&
  94.163 -         acm_secondary_ops->is_default_policy() )
  94.164 -        require_update = 0;
  94.165 -
  94.166 -    write_unlock(&acm_bin_pol_rwlock);
  94.167 -
  94.168 -    return ACM_OK;
  94.169 -
  94.170 -error_lock_free:
  94.171 -    if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) )
  94.172 -    {
  94.173 -        acm_doms_restore_ssidref();
  94.174 -    }
  94.175 -    do_chwall_init_state_curr(NULL);
  94.176 -    write_unlock(&acm_bin_pol_rwlock);
  94.177 -
  94.178 -    return -EFAULT;
  94.179 -}
  94.180 -
  94.181 -
  94.182 -int
  94.183 -do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy,
  94.184 -                  struct acm_sized_buffer *deletions,
  94.185 -                  struct acm_sized_buffer *ssidchanges,
  94.186 -                  struct acm_sized_buffer *errors)
  94.187 -{
  94.188 -    struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
  94.189 -
  94.190 -    /* some sanity checking */
  94.191 -    if ( (be32_to_cpu(pol->magic) != ACM_MAGIC) ||
  94.192 -         (buf_size != be32_to_cpu(pol->len)) ||
  94.193 -         (be32_to_cpu(pol->policy_version) != ACM_POLICY_VERSION) )
  94.194 -    {
  94.195 -        printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
  94.196 -        goto error_free;
  94.197 -    }
  94.198 -
  94.199 -    if ( acm_active_security_policy == ACM_POLICY_UNDEFINED )
  94.200 -    {
  94.201 -        /* setup the policy with the boot policy */
  94.202 -        if ( acm_init_binary_policy(
  94.203 -                             (be32_to_cpu(pol->secondary_policy_code) << 4) |
  94.204 -                              be32_to_cpu(pol->primary_policy_code)) )
  94.205 -        {
  94.206 -            goto error_free;
  94.207 -        }
  94.208 -        acm_active_security_policy = (acm_bin_pol.secondary_policy_code << 4) |
  94.209 -                                      acm_bin_pol.primary_policy_code;
  94.210 -    }
  94.211 -
  94.212 -    /* once acm_active_security_policy is set, it cannot be changed */
  94.213 -    if ( (be32_to_cpu(pol->primary_policy_code) !=
  94.214 -                                        acm_bin_pol.primary_policy_code) ||
  94.215 -         (be32_to_cpu(pol->secondary_policy_code) !=
  94.216 -                                        acm_bin_pol.secondary_policy_code) )
  94.217 -    {
  94.218 -        printkd("%s: Wrong policy type in boot policy!\n", __func__);
  94.219 -        goto error_free;
  94.220 -    }
  94.221 -
  94.222 -    return _acm_update_policy(buf, buf_size, is_bootpolicy,
  94.223 -                              pol,
  94.224 -                              deletions, ssidchanges,
  94.225 -                              errors);
  94.226 -
  94.227 - error_free:
  94.228 -    printk("%s: Error setting policy.\n", __func__);
  94.229 -    return -EFAULT;
  94.230 -}
  94.231 -
  94.232 -int
  94.233 -acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size)
  94.234 -{ 
  94.235 -    u8 *policy_buffer;
  94.236 -    int ret;
  94.237 -    struct acm_policy_buffer *bin_pol;
  94.238 -
  94.239 -    if ( buf_size < sizeof(struct acm_policy_buffer) )
  94.240 -        return -EFAULT;
  94.241 -
  94.242 -    if ( (policy_buffer = xmalloc_array(u8, buf_size)) == NULL )
  94.243 -        return -ENOMEM;
  94.244 -
  94.245 -    read_lock(&acm_bin_pol_rwlock);
  94.246 -
  94.247 -    bin_pol = (struct acm_policy_buffer *)policy_buffer;
  94.248 -    bin_pol->magic = cpu_to_be32(ACM_MAGIC);
  94.249 -    bin_pol->primary_policy_code =
  94.250 -                                cpu_to_be32(acm_bin_pol.primary_policy_code);
  94.251 -    bin_pol->secondary_policy_code =
  94.252 -                                cpu_to_be32(acm_bin_pol.secondary_policy_code);
  94.253 -
  94.254 -    bin_pol->len = cpu_to_be32(sizeof(struct acm_policy_buffer));
  94.255 -    bin_pol->policy_reference_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
  94.256 -    bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
  94.257 -    bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
  94.258 -
  94.259 -    memcpy(&bin_pol->xml_pol_version,
  94.260 -           &acm_bin_pol.xml_pol_version,
  94.261 -           sizeof(struct acm_policy_version));
  94.262 -
  94.263 -    ret = acm_dump_policy_reference(
  94.264 -               policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset),
  94.265 -               buf_size - be32_to_cpu(bin_pol->policy_reference_offset));
  94.266 -
  94.267 -    if ( ret < 0 )
  94.268 -        goto error_free_unlock;
  94.269 -
  94.270 -    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
  94.271 -    bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
  94.272 -
  94.273 -    ret = acm_primary_ops->dump_binary_policy(
  94.274 -                 policy_buffer + be32_to_cpu(bin_pol->primary_buffer_offset),
  94.275 -                 buf_size - be32_to_cpu(bin_pol->primary_buffer_offset));
  94.276 -
  94.277 -    if ( ret < 0 )
  94.278 -        goto error_free_unlock;
  94.279 -
  94.280 -    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
  94.281 -    bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
  94.282 -
  94.283 -    ret = acm_secondary_ops->dump_binary_policy(
  94.284 -               policy_buffer + be32_to_cpu(bin_pol->secondary_buffer_offset),
  94.285 -               buf_size - be32_to_cpu(bin_pol->secondary_buffer_offset));
  94.286 -
  94.287 -    if ( ret < 0 )
  94.288 -        goto error_free_unlock;
  94.289 -
  94.290 -    bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret);
  94.291 -    if ( copy_to_guest(buf, policy_buffer, be32_to_cpu(bin_pol->len)) )
  94.292 -        goto error_free_unlock;
  94.293 -
  94.294 -    read_unlock(&acm_bin_pol_rwlock);
  94.295 -    xfree(policy_buffer);
  94.296 -
  94.297 -    return ACM_OK;
  94.298 -
  94.299 - error_free_unlock:
  94.300 -    read_unlock(&acm_bin_pol_rwlock);
  94.301 -    printk("%s: Error getting policy.\n", __func__);
  94.302 -    xfree(policy_buffer);
  94.303 -
  94.304 -    return -EFAULT;
  94.305 -}
  94.306 -
  94.307 -int
  94.308 -acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size)
  94.309 -{ 
  94.310 -    /* send stats to user space */
  94.311 -    u8 *stats_buffer;
  94.312 -    int len1, len2;
  94.313 -    struct acm_stats_buffer acm_stats;
  94.314 -
  94.315 -    if ( (stats_buffer = xmalloc_array(u8, buf_size)) == NULL )
  94.316 -        return -ENOMEM;
  94.317 -
  94.318 -    read_lock(&acm_bin_pol_rwlock);
  94.319 -     
  94.320 -    len1 = acm_primary_ops->dump_statistics(
  94.321 -                             stats_buffer + sizeof(struct acm_stats_buffer),
  94.322 -                             buf_size - sizeof(struct acm_stats_buffer));
  94.323 -    if ( len1 < 0 )
  94.324 -        goto error_lock_free;
  94.325 -      
  94.326 -    len2 = acm_secondary_ops->dump_statistics(
  94.327 -                      stats_buffer + sizeof(struct acm_stats_buffer) + len1,
  94.328 -                      buf_size - sizeof(struct acm_stats_buffer) - len1);
  94.329 -    if ( len2 < 0 )
  94.330 -        goto error_lock_free;
  94.331 -
  94.332 -    acm_stats.magic = cpu_to_be32(ACM_MAGIC);
  94.333 -    acm_stats.primary_policy_code =
  94.334 -                           cpu_to_be32(acm_bin_pol.primary_policy_code);
  94.335 -    acm_stats.secondary_policy_code =
  94.336 -                           cpu_to_be32(acm_bin_pol.secondary_policy_code);
  94.337 -    acm_stats.primary_stats_offset =
  94.338 -                           cpu_to_be32(sizeof(struct acm_stats_buffer));
  94.339 -    acm_stats.secondary_stats_offset =
  94.340 -                           cpu_to_be32(sizeof(struct acm_stats_buffer) + len1);
  94.341 -    acm_stats.len = cpu_to_be32(sizeof(struct acm_stats_buffer) + len1 + len2);
  94.342 -
  94.343 -    memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
  94.344 -
  94.345 -    if ( copy_to_guest(buf,
  94.346 -                       stats_buffer,
  94.347 -                       sizeof(struct acm_stats_buffer) + len1 + len2) )
  94.348 -        goto error_lock_free;
  94.349 -
  94.350 -    read_unlock(&acm_bin_pol_rwlock);
  94.351 -    xfree(stats_buffer);
  94.352 -
  94.353 -    return ACM_OK;
  94.354 -
  94.355 - error_lock_free:
  94.356 -    read_unlock(&acm_bin_pol_rwlock);
  94.357 -    xfree(stats_buffer);
  94.358 -
  94.359 -    return -EFAULT;
  94.360 -}
  94.361 -
  94.362 -
  94.363 -int
  94.364 -acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size)
  94.365 -{
  94.366 -    /* send stats to user space */
  94.367 -    u8 *ssid_buffer;
  94.368 -    int ret;
  94.369 -    struct acm_ssid_buffer *acm_ssid;
  94.370 -    if ( buf_size < sizeof(struct acm_ssid_buffer) )
  94.371 -        return -EFAULT;
  94.372 -
  94.373 -    if ( (ssid_buffer = xmalloc_array(u8, buf_size)) == NULL )
  94.374 -        return -ENOMEM;
  94.375 -
  94.376 -    read_lock(&acm_bin_pol_rwlock);
  94.377 -
  94.378 -    acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
  94.379 -    acm_ssid->len = sizeof(struct acm_ssid_buffer);
  94.380 -    acm_ssid->ssidref = ssidref;
  94.381 -    acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
  94.382 -    acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
  94.383 -
  94.384 -    acm_ssid->policy_reference_offset = acm_ssid->len;
  94.385 -    ret = acm_dump_policy_reference(
  94.386 -                          ssid_buffer + acm_ssid->policy_reference_offset,
  94.387 -                          buf_size - acm_ssid->policy_reference_offset);
  94.388 -    if ( ret < 0 )
  94.389 -        goto error_free_unlock;
  94.390 -
  94.391 -    acm_ssid->len += ret;
  94.392 -    acm_ssid->primary_types_offset = acm_ssid->len;
  94.393 -
  94.394 -    /* ret >= 0 --> ret == max_types */
  94.395 -    ret = acm_primary_ops->dump_ssid_types(
  94.396 -                                 ACM_PRIMARY(ssidref),
  94.397 -                                 ssid_buffer + acm_ssid->primary_types_offset,
  94.398 -                                 buf_size - acm_ssid->primary_types_offset);
  94.399 -    if ( ret < 0 )
  94.400 -        goto error_free_unlock;
  94.401 -
  94.402 -    acm_ssid->len += ret;
  94.403 -    acm_ssid->primary_max_types = ret;
  94.404 -    acm_ssid->secondary_types_offset = acm_ssid->len;
  94.405 -
  94.406 -    ret = acm_secondary_ops->dump_ssid_types(
  94.407 -                             ACM_SECONDARY(ssidref),
  94.408 -                             ssid_buffer + acm_ssid->secondary_types_offset,
  94.409 -                             buf_size - acm_ssid->secondary_types_offset);
  94.410 -    if ( ret < 0 )
  94.411 -        goto error_free_unlock;
  94.412 -
  94.413 -    acm_ssid->len += ret;
  94.414 -    acm_ssid->secondary_max_types = ret;
  94.415 -
  94.416 -    if ( copy_to_guest(buf, ssid_buffer, acm_ssid->len) )
  94.417 -        goto error_free_unlock;
  94.418 -
  94.419 -    read_unlock(&acm_bin_pol_rwlock);
  94.420 -    xfree(ssid_buffer);
  94.421 -
  94.422 -    return ACM_OK;
  94.423 -
  94.424 - error_free_unlock:
  94.425 -    read_unlock(&acm_bin_pol_rwlock);
  94.426 -    printk("%s: Error getting ssid.\n", __func__);
  94.427 -    xfree(ssid_buffer);
  94.428 -
  94.429 -    return -ENOMEM;
  94.430 -}
  94.431 -
  94.432 -int
  94.433 -acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook)
  94.434 -{
  94.435 -    int ret = ACM_ACCESS_DENIED;
  94.436 -    switch ( hook )
  94.437 -    {
  94.438 -
  94.439 -    case ACMHOOK_sharing:
  94.440 -        /* Sharing hook restricts access in STE policy only */
  94.441 -        ret = acm_sharing(ssidref1, ssidref2);
  94.442 -        break;
  94.443 -
  94.444 -    case ACMHOOK_authorization:
  94.445 -        ret = acm_authorization(ssidref1, ssidref2);
  94.446 -        break;
  94.447 -
  94.448 -    default:
  94.449 -        /* deny */
  94.450 -        break;
  94.451 -    }
  94.452 -
  94.453 -    printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
  94.454 -            __func__, ssidref1, ssidref2,
  94.455 -            (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
  94.456 -
  94.457 -    return ret;
  94.458 -}
  94.459 -
  94.460 -
  94.461 -
  94.462 -/*
  94.463 -   Check if an ssidref of the current policy type is being used by any
  94.464 -   domain.
  94.465 - */
  94.466 -static int
  94.467 -acm_check_used_ssidref(uint32_t policy_type, uint32_t search_ssidref,
  94.468 -                       struct acm_sized_buffer *errors)
  94.469 -{
  94.470 -    int rc = 0;
  94.471 -    struct acm_ssid_domain *rawssid;
  94.472 -
  94.473 -    read_lock(&ssid_list_rwlock);
  94.474 -
  94.475 -    for_each_acmssid( rawssid )
  94.476 -    {
  94.477 -        ssidref_t ssidref;
  94.478 -        void *s = GET_SSIDP(policy_type, rawssid);
  94.479 -
  94.480 -        if ( policy_type == ACM_CHINESE_WALL_POLICY )
  94.481 -        {
  94.482 -            ssidref = ((struct chwall_ssid *)s)->chwall_ssidref;
  94.483 -        } else {
  94.484 -            ssidref = ((struct ste_ssid *)s)->ste_ssidref;
  94.485 -        }
  94.486 -        gdprintk(XENLOG_INFO,"domid=%d: search ssidref=%d, ssidref=%d\n",
  94.487 -                 rawssid->domainid,search_ssidref,ssidref);
  94.488 -        if ( ssidref == search_ssidref )
  94.489 -        {
  94.490 -            /* one is enough */
  94.491 -            acm_array_append_tuple(errors, ACM_SSIDREF_IN_USE, search_ssidref);
  94.492 -            rc = 1;
  94.493 -            break;
  94.494 -        }
  94.495 -    }
  94.496 -
  94.497 -    read_unlock(&ssid_list_rwlock);
  94.498 -
  94.499 -    return rc;
  94.500 -}
  94.501 -
  94.502 -
  94.503 -/*
  94.504 - * Translate a current ssidref into its future representation under
  94.505 - * the new policy.
  94.506 - * The map provides translation of ssidrefs from old to new in tuples
  94.507 - * of (old ssidref, new ssidref).
  94.508 - */
  94.509 -static ssidref_t
  94.510 -oldssid_to_newssid(const struct acm_ssid_domain *rawssid,
  94.511 -                   const struct acm_sized_buffer *map)
  94.512 -{
  94.513 -    uint i;
  94.514 -
  94.515 -    if ( rawssid != NULL )
  94.516 -    {
  94.517 -        ssidref_t ssid = rawssid->ssidref & 0xffff;
  94.518 -        for ( i = 0; i + 1 < map->num_items; i += 2 )
  94.519 -        {
  94.520 -            if ( map->array[i] == ssid )
  94.521 -            {
  94.522 -                return (map->array[i+1] << 16 | map->array[i+1]);
  94.523 -            }
  94.524 -        }
  94.525 -    }
  94.526 -    return ACM_INVALID_SSIDREF;
  94.527 -}
  94.528 -
  94.529 -
  94.530 -/*
  94.531 - * Assign an ssidref to the CHWALL policy component of the domain
  94.532 - */
  94.533 -static void
  94.534 -acm_pri_policy_assign_ssidref(struct acm_ssid_domain *rawssid,
  94.535 -                              ssidref_t new_ssid)
  94.536 -{
  94.537 -    struct chwall_ssid *chwall = (struct chwall_ssid *)rawssid->primary_ssid;
  94.538 -    chwall->chwall_ssidref = new_ssid;
  94.539 -}
  94.540 -
  94.541 -
  94.542 -/*
  94.543 - * Assign an ssidref to the STE policy component of the domain
  94.544 - */
  94.545 -static void
  94.546 -acm_sec_policy_assign_ssidref(struct acm_ssid_domain *rawssid,
  94.547 -                              ssidref_t new_ssid)
  94.548 -{
  94.549 -    struct ste_ssid *ste = (struct ste_ssid *)rawssid->secondary_ssid;
  94.550 -    ste->ste_ssidref = new_ssid;
  94.551 -}
  94.552 -
  94.553 -/*
  94.554 -   Change the ssidrefs on each domain using a passed translation function;
  94.555 - */
  94.556 -static void
  94.557 -acm_doms_change_ssidref(ssidref_t (*translator_fn)
  94.558 -                          (const struct acm_ssid_domain *,
  94.559 -                           const struct acm_sized_buffer *),
  94.560 -                        struct acm_sized_buffer *translation_map)
  94.561 -{
  94.562 -    struct acm_ssid_domain *rawssid;
  94.563 -
  94.564 -    write_lock(&ssid_list_rwlock);
  94.565 -
  94.566 -    for_each_acmssid( rawssid )
  94.567 -    {
  94.568 -        ssidref_t new_ssid;
  94.569 -
  94.570 -        rawssid->old_ssidref = rawssid->ssidref;
  94.571 -
  94.572 -        new_ssid = translator_fn(rawssid, translation_map);
  94.573 -        if ( new_ssid == ACM_INVALID_SSIDREF )
  94.574 -        {
  94.575 -            /* means no mapping found, so no change -- old = new */
  94.576 -            continue;
  94.577 -        }
  94.578 -
  94.579 -        acm_pri_policy_assign_ssidref(rawssid, ACM_PRIMARY  (new_ssid) );
  94.580 -        acm_sec_policy_assign_ssidref(rawssid, ACM_SECONDARY(new_ssid) );
  94.581 -
  94.582 -        rawssid->ssidref = new_ssid;
  94.583 -    }
  94.584 -
  94.585 -    write_unlock(&ssid_list_rwlock);
  94.586 -}
  94.587 -
  94.588 -/*
  94.589 - * Restore the previous ssidref values on all domains
  94.590 - */
  94.591 -static void
  94.592 -acm_doms_restore_ssidref(void)
  94.593 -{
  94.594 -    struct acm_ssid_domain *rawssid;
  94.595 -
  94.596 -    write_lock(&ssid_list_rwlock);
  94.597 -
  94.598 -    for_each_acmssid( rawssid )
  94.599 -    {
  94.600 -        ssidref_t old_ssid;
  94.601 -
  94.602 -        if ( rawssid->old_ssidref == rawssid->ssidref )
  94.603 -            continue;
  94.604 -
  94.605 -        old_ssid = rawssid->old_ssidref & 0xffff;
  94.606 -        rawssid->ssidref = rawssid->old_ssidref;
  94.607 -
  94.608 -        acm_pri_policy_assign_ssidref(rawssid, old_ssid);
  94.609 -        acm_sec_policy_assign_ssidref(rawssid, old_ssid);
  94.610 -    }
  94.611 -
  94.612 -    write_unlock(&ssid_list_rwlock);
  94.613 -}
  94.614 -
  94.615 -
  94.616 -/*
  94.617 -   Check the list of domains whether either one of them uses a
  94.618 -   to-be-deleted ssidref.
  94.619 - */
  94.620 -static int
  94.621 -acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels,
  94.622 -                           struct acm_sized_buffer *errors)
  94.623 -{
  94.624 -    int rc = 0;
  94.625 -    uint idx;
  94.626 -    /* check for running domains that should not be there anymore */
  94.627 -    for ( idx = 0; idx < dels->num_items; idx++ )
  94.628 -    {
  94.629 -        if ( acm_check_used_ssidref(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
  94.630 -                                    dels->array[idx],
  94.631 -                                    errors) > 0 ||
  94.632 -             acm_check_used_ssidref(ACM_CHINESE_WALL_POLICY,
  94.633 -                                    dels->array[idx],
  94.634 -                                    errors) > 0)
  94.635 -        {
  94.636 -            rc = ACM_ERROR;
  94.637 -            break;
  94.638 -        }
  94.639 -    }
  94.640 -    return rc;
  94.641 -}
  94.642 -
  94.643 -
  94.644 -/*
  94.645 - * Change the policy of the system.
  94.646 - */
  94.647 -int
  94.648 -acm_change_policy(struct acm_change_policy *chgpolicy)
  94.649 -{
  94.650 -    int rc = 0;
  94.651 -    u8 *binpolicy = NULL;
  94.652 -    struct acm_sized_buffer dels =
  94.653 -    {
  94.654 -        .array = NULL,
  94.655 -    };
  94.656 -    struct acm_sized_buffer ssidmap =
  94.657 -    {
  94.658 -        .array = NULL,
  94.659 -    };
  94.660 -    struct acm_sized_buffer errors =
  94.661 -    {
  94.662 -        .array = NULL,
  94.663 -    };
  94.664 -
  94.665 -    gdprintk(XENLOG_INFO, "change policy operation\n");
  94.666 -
  94.667 -    if ( (chgpolicy->delarray_size > 4096) ||
  94.668 -         (chgpolicy->chgarray_size > 4096) ||
  94.669 -         (chgpolicy->errarray_size > 4096))
  94.670 -    {
  94.671 -        return ACM_ERROR;
  94.672 -    }
  94.673 -
  94.674 -    dels.num_items = chgpolicy->delarray_size / sizeof(uint32_t);
  94.675 -    if ( dels.num_items > 0 )
  94.676 -    {
  94.677 -        dels.array = xmalloc_array(uint32_t, dels.num_items);
  94.678 -        if ( dels.array == NULL )
  94.679 -        {
  94.680 -            rc = -ENOMEM;
  94.681 -            goto acm_chg_policy_exit;
  94.682 -        }
  94.683 -    }
  94.684 -
  94.685 -    ssidmap.num_items = chgpolicy->chgarray_size / sizeof(uint32_t);
  94.686 -    if ( ssidmap.num_items > 0 )
  94.687 -    {
  94.688 -        ssidmap.array = xmalloc_array(uint32_t, ssidmap.num_items);
  94.689 -        if ( ssidmap.array == NULL )
  94.690 -        {
  94.691 -            rc = -ENOMEM;
  94.692 -            goto acm_chg_policy_exit;
  94.693 -        }
  94.694 -    }
  94.695 -
  94.696 -    errors.num_items = chgpolicy->errarray_size / sizeof(uint32_t);
  94.697 -    if ( errors.num_items > 0 )
  94.698 -    {
  94.699 -        errors.array = xmalloc_array(uint32_t, errors.num_items);
  94.700 -        if ( errors.array == NULL )
  94.701 -        {
  94.702 -            rc = -ENOMEM;
  94.703 -            goto acm_chg_policy_exit;
  94.704 -        }
  94.705 -        memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items);
  94.706 -    }
  94.707 -
  94.708 -    binpolicy = xmalloc_array(u8,
  94.709 -                              chgpolicy->policy_pushcache_size);
  94.710 -    if ( binpolicy == NULL )
  94.711 -    {
  94.712 -        rc = -ENOMEM;
  94.713 -        goto acm_chg_policy_exit;
  94.714 -    }
  94.715 -
  94.716 -    if ( copy_from_guest(dels.array,
  94.717 -                         chgpolicy->del_array,
  94.718 -                         dels.num_items) ||
  94.719 -         copy_from_guest(ssidmap.array,
  94.720 -                         chgpolicy->chg_array,
  94.721 -                         ssidmap.num_items) ||
  94.722 -         copy_from_guest(binpolicy,
  94.723 -                         chgpolicy->policy_pushcache,
  94.724 -                         chgpolicy->policy_pushcache_size ))
  94.725 -    {
  94.726 -        rc = -EFAULT;
  94.727 -        goto acm_chg_policy_exit;
  94.728 -    }
  94.729 -
  94.730 -    rc = do_acm_set_policy(binpolicy,
  94.731 -                           chgpolicy->policy_pushcache_size,
  94.732 -                           0,
  94.733 -                           &dels, &ssidmap, &errors);
  94.734 -
  94.735 -    if ( (errors.num_items > 0) &&
  94.736 -         copy_to_guest(chgpolicy->err_array,
  94.737 -                       errors.array,
  94.738 -                       errors.num_items ) )
  94.739 -    {
  94.740 -        rc = -EFAULT;
  94.741 -        goto acm_chg_policy_exit;
  94.742 -    }
  94.743 -
  94.744 -
  94.745 -acm_chg_policy_exit:
  94.746 -    xfree(dels.array);
  94.747 -    xfree(ssidmap.array);
  94.748 -    xfree(errors.array);
  94.749 -    xfree(binpolicy);
  94.750 -
  94.751 -    return rc;
  94.752 -}
  94.753 -
  94.754 -
  94.755 -/*
  94.756 - * Lookup the new ssidref given the domain's id.
  94.757 - * The translation map provides a list of tuples in the format
  94.758 - * (domid, new ssidref).
  94.759 - */
  94.760 -static ssidref_t
  94.761 -domid_to_newssid(const struct acm_ssid_domain *rawssid,
  94.762 -                 const struct acm_sized_buffer *map)
  94.763 -{
  94.764 -    domid_t domid = rawssid->domainid;
  94.765 -    uint i;
  94.766 -    for ( i = 0; (i+1) < map->num_items; i += 2 )
  94.767 -    {
  94.768 -        if ( map->array[i] == domid )
  94.769 -            return (ssidref_t)map->array[i+1];
  94.770 -    }
  94.771 -    return ACM_INVALID_SSIDREF;
  94.772 -}
  94.773 -
  94.774 -
  94.775 -int
  94.776 -do_acm_relabel_doms(struct acm_sized_buffer *relabel_map,
  94.777 -                    struct acm_sized_buffer *errors)
  94.778 -{
  94.779 -    int rc = 0, irc;
  94.780 -
  94.781 -    write_lock(&acm_bin_pol_rwlock);
  94.782 -
  94.783 -    acm_doms_change_ssidref(domid_to_newssid, relabel_map);
  94.784 -
  94.785 -    /* run tests; collect as much error info as possible */
  94.786 -    irc =  do_chwall_init_state_curr(errors);
  94.787 -    irc += do_ste_init_state_curr(errors);
  94.788 -    if ( irc != 0 )
  94.789 -    {
  94.790 -        rc = -EFAULT;
  94.791 -        goto acm_relabel_doms_lock_err_exit;
  94.792 -    }
  94.793 -
  94.794 -    write_unlock(&acm_bin_pol_rwlock);
  94.795 -
  94.796 -    return rc;
  94.797 -
  94.798 -acm_relabel_doms_lock_err_exit:
  94.799 -    /* revert the new ssidref assignment */
  94.800 -    acm_doms_restore_ssidref();
  94.801 -    do_chwall_init_state_curr(NULL);
  94.802 -
  94.803 -    write_unlock(&acm_bin_pol_rwlock);
  94.804 -
  94.805 -    return rc;
  94.806 -}
  94.807 -
  94.808 -
  94.809 -int
  94.810 -acm_relabel_domains(struct acm_relabel_doms *relabel)
  94.811 -{
  94.812 -    int rc = ACM_OK;
  94.813 -    struct acm_sized_buffer relabels =
  94.814 -    {
  94.815 -        .array = NULL,
  94.816 -    };
  94.817 -    struct acm_sized_buffer errors =
  94.818 -    {
  94.819 -        .array = NULL,
  94.820 -    };
  94.821 -
  94.822 -    if ( relabel->relabel_map_size > 4096 )
  94.823 -    {
  94.824 -        return ACM_ERROR;
  94.825 -    }
  94.826 -
  94.827 -    relabels.num_items = relabel->relabel_map_size / sizeof(uint32_t);
  94.828 -    if ( relabels.num_items > 0 )
  94.829 -    {
  94.830 -        relabels.array = xmalloc_array(uint32_t, relabels.num_items);
  94.831 -        if ( relabels.array == NULL )
  94.832 -        {
  94.833 -            rc = -ENOMEM;
  94.834 -            goto acm_relabel_doms_exit;
  94.835 -        }
  94.836 -    }
  94.837 -
  94.838 -    errors.num_items = relabel->errarray_size / sizeof(uint32_t);
  94.839 -    if ( errors.num_items > 0 )
  94.840 -    {
  94.841 -        errors.array = xmalloc_array(uint32_t, errors.num_items);
  94.842 -        if ( errors.array == NULL )
  94.843 -        {
  94.844 -            rc = -ENOMEM;
  94.845 -            goto acm_relabel_doms_exit;
  94.846 -        }
  94.847 -        memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items);
  94.848 -    }
  94.849 -
  94.850 -    if ( copy_from_guest(relabels.array,
  94.851 -                         relabel->relabel_map,
  94.852 -                         relabels.num_items) )
  94.853 -    {
  94.854 -        rc = -EFAULT;
  94.855 -        goto acm_relabel_doms_exit;
  94.856 -    }
  94.857 -
  94.858 -    rc = do_acm_relabel_doms(&relabels, &errors);
  94.859 -
  94.860 -    if ( copy_to_guest(relabel->err_array,
  94.861 -                       errors.array,
  94.862 -                       errors.num_items ) )
  94.863 -        rc = -EFAULT;
  94.864 -
  94.865 -acm_relabel_doms_exit:
  94.866 -    xfree(relabels.array);
  94.867 -    xfree(errors.array);
  94.868 -    return rc;
  94.869 -}
  94.870 -
  94.871 -/*
  94.872 - * Local variables:
  94.873 - * mode: C
  94.874 - * c-set-style: "BSD"
  94.875 - * c-basic-offset: 4
  94.876 - * tab-width: 4
  94.877 - * indent-tabs-mode: nil
  94.878 - * End:
  94.879 - */
    95.1 --- a/xen/acm/acm_simple_type_enforcement_hooks.c	Thu Sep 06 09:05:26 2007 -0600
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,914 +0,0 @@
    95.4 -/****************************************************************
    95.5 - * acm_simple_type_enforcement_hooks.c
    95.6 - * 
    95.7 - * Copyright (C) 2005 IBM Corporation
    95.8 - *
    95.9 - * Author:
   95.10 - * Reiner Sailer <sailer@watson.ibm.com>
   95.11 - *
   95.12 - * Contributors:
   95.13 - * Stefan Berger <stefanb@watson.ibm.com>
   95.14 - *         support for network order binary policies
   95.15 - *
   95.16 - * This program is free software; you can redistribute it and/or
   95.17 - * modify it under the terms of the GNU General Public License as
   95.18 - * published by the Free Software Foundation, version 2 of the
   95.19 - * License.
   95.20 - *
   95.21 - * sHype Simple Type Enforcement for Xen
   95.22 - *     STE allows to control which domains can setup sharing
   95.23 - *     (eventchannels right now) with which other domains. Hooks
   95.24 - *     are defined and called throughout Xen when domains bind to
   95.25 - *     shared resources (setup eventchannels) and a domain is allowed
   95.26 - *     to setup sharing with another domain if and only if both domains
   95.27 - *     share at least on common type.
   95.28 - *
   95.29 - */
   95.30 -
   95.31 -#include <xen/lib.h>
   95.32 -#include <asm/types.h>
   95.33 -#include <asm/current.h>
   95.34 -#include <acm/acm_hooks.h>
   95.35 -#include <asm/atomic.h>
   95.36 -#include <acm/acm_endian.h>
   95.37 -#include <acm/acm_core.h>
   95.38 -
   95.39 -ssidref_t dom0_ste_ssidref = 0x0001;
   95.40 -
   95.41 -/* local cache structures for STE policy */
   95.42 -struct ste_binary_policy ste_bin_pol;
   95.43 -
   95.44 -static inline int have_common_type (ssidref_t ref1, ssidref_t ref2)
   95.45 -{
   95.46 -    int i;
   95.47 -
   95.48 -    if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs &&
   95.49 -         ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs )
   95.50 -    {
   95.51 -        for( i = 0; i< ste_bin_pol.max_types; i++ )
   95.52 -            if ( ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] &&
   95.53 -                 ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i])
   95.54 -            {
   95.55 -                printkd("%s: common type #%02x.\n", __func__, i);
   95.56 -                return 1;
   95.57 -            }
   95.58 -    }
   95.59 -    return 0;
   95.60 -}
   95.61 -
   95.62 -static inline int is_superset(ssidref_t ref1, ssidref_t ref2)
   95.63 -{
   95.64 -    int i;
   95.65 -
   95.66 -    if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs &&
   95.67 -         ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs )
   95.68 -    {
   95.69 -        for( i = 0; i< ste_bin_pol.max_types; i++ )
   95.70 -            if (!ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] &&
   95.71 -                 ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i])
   95.72 -            {
   95.73 -                return 0;
   95.74 -            }
   95.75 -    } else {
   95.76 -        return 0;
   95.77 -    }
   95.78 -    return 1;
   95.79 -}
   95.80 -
   95.81 -
   95.82 -/* Helper function: return = (subj and obj share a common type) */
   95.83 -static int share_common_type(struct domain *subj, struct domain *obj)
   95.84 -{
   95.85 -    ssidref_t ref_s, ref_o;
   95.86 -    int ret;
   95.87 -
   95.88 -    if ( (subj == NULL) || (obj == NULL) ||
   95.89 -         (subj->ssid == NULL) || (obj->ssid == NULL) )
   95.90 -        return 0;
   95.91 -
   95.92 -    read_lock(&acm_bin_pol_rwlock);
   95.93 -
   95.94 -    /* lookup the policy-local ssids */
   95.95 -    ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
   95.96 -                       (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref;
   95.97 -    ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   95.98 -                       (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref;
   95.99 -    /* check whether subj and obj share a common ste type */
  95.100 -    ret = have_common_type(ref_s, ref_o);
  95.101 -
  95.102 -    read_unlock(&acm_bin_pol_rwlock);
  95.103 -
  95.104 -    return ret;
  95.105 -}
  95.106 -
  95.107 -/*
  95.108 - * Initializing STE policy (will be filled by policy partition
  95.109 - * using setpolicy command)
  95.110 - */
  95.111 -int acm_init_ste_policy(void)
  95.112 -{
  95.113 -    /* minimal startup policy; policy write-locked already */
  95.114 -    ste_bin_pol.max_types = 1;
  95.115 -    ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref;
  95.116 -    ste_bin_pol.ssidrefs =
  95.117 -            (domaintype_t *)xmalloc_array(domaintype_t,
  95.118 -                                          ste_bin_pol.max_types *
  95.119 -                                          ste_bin_pol.max_ssidrefs);
  95.120 -
  95.121 -    if (ste_bin_pol.ssidrefs == NULL)
  95.122 -        return ACM_INIT_SSID_ERROR;
  95.123 -
  95.124 -    memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) *
  95.125 -                                    ste_bin_pol.max_types *
  95.126 -                                    ste_bin_pol.max_ssidrefs);
  95.127 -
  95.128 -    /* initialize state so that dom0 can start up and communicate with itself */
  95.129 -    ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1;
  95.130 -
  95.131 -    /* init stats */
  95.132 -    atomic_set(&(ste_bin_pol.ec_eval_count), 0);
  95.133 -    atomic_set(&(ste_bin_pol.ec_denied_count), 0);
  95.134 -    atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
  95.135 -    atomic_set(&(ste_bin_pol.gt_eval_count), 0);
  95.136 -    atomic_set(&(ste_bin_pol.gt_denied_count), 0);
  95.137 -    atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
  95.138 -
  95.139 -    return ACM_OK;
  95.140 -}
  95.141 -
  95.142 -
  95.143 -/* ste initialization function hooks */
  95.144 -static int
  95.145 -ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
  95.146 -{
  95.147 -    int i;
  95.148 -    struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid);
  95.149 -
  95.150 -    if ( ste_ssidp == NULL )
  95.151 -        return ACM_INIT_SSID_ERROR;
  95.152 -
  95.153 -    /* get policy-local ssid reference */
  95.154 -    ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
  95.155 -                                         ssidref);
  95.156 -
  95.157 -    if ( (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) )
  95.158 -    {
  95.159 -        printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n",
  95.160 -                __func__, ste_ssidp->ste_ssidref);
  95.161 -        xfree(ste_ssidp);
  95.162 -        return ACM_INIT_SSID_ERROR;
  95.163 -    }
  95.164 -    /* clean ste cache */
  95.165 -    for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
  95.166 -        ste_ssidp->ste_cache[i].valid = ACM_STE_free;
  95.167 -
  95.168 -    (*ste_ssid) = ste_ssidp;
  95.169 -    printkd("%s: determined ste_ssidref to %x.\n", 
  95.170 -            __func__, ste_ssidp->ste_ssidref);
  95.171 -
  95.172 -    return ACM_OK;
  95.173 -}
  95.174 -
  95.175 -
  95.176 -static void
  95.177 -ste_free_domain_ssid(void *ste_ssid)
  95.178 -{
  95.179 -    xfree(ste_ssid);
  95.180 -    return;
  95.181 -}
  95.182 -
  95.183 -/* dump type enforcement cache; policy read-locked already */
  95.184 -static int 
  95.185 -ste_dump_policy(u8 *buf, u32 buf_size) {
  95.186 -    struct acm_ste_policy_buffer *ste_buf =
  95.187 -                                  (struct acm_ste_policy_buffer *)buf;
  95.188 -    int ret = 0;
  95.189 -
  95.190 -    if ( buf_size < sizeof(struct acm_ste_policy_buffer) )
  95.191 -        return -EINVAL;
  95.192 -
  95.193 -    ste_buf->ste_max_types = cpu_to_be32(ste_bin_pol.max_types);
  95.194 -    ste_buf->ste_max_ssidrefs = cpu_to_be32(ste_bin_pol.max_ssidrefs);
  95.195 -    ste_buf->policy_code = cpu_to_be32(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
  95.196 -    ste_buf->ste_ssid_offset =
  95.197 -                           cpu_to_be32(sizeof(struct acm_ste_policy_buffer));
  95.198 -    ret = be32_to_cpu(ste_buf->ste_ssid_offset) +
  95.199 -        sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
  95.200 -
  95.201 -    ret = (ret + 7) & ~7;
  95.202 -
  95.203 -    if (buf_size < ret)
  95.204 -        return -EINVAL;
  95.205 -
  95.206 -    /* now copy buffer over */
  95.207 -    arrcpy(buf + be32_to_cpu(ste_buf->ste_ssid_offset),
  95.208 -           ste_bin_pol.ssidrefs,
  95.209 -           sizeof(domaintype_t),
  95.210 -           ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
  95.211 -
  95.212 -    return ret;
  95.213 -}
  95.214 -
  95.215 -/*
  95.216 - * ste_init_state is called when a policy is changed to detect violations
  95.217 - * (return != 0). from a security point of view, we simulate that all
  95.218 - * running domains are re-started and all sharing decisions are replayed
  95.219 - * to detect violations or current sharing behavior (right now:
  95.220 - * event_channels, future: also grant_tables)
  95.221 - */ 
  95.222 -static int
  95.223 -ste_init_state(struct acm_sized_buffer *errors)
  95.224 -{
  95.225 -    int violation = 1;
  95.226 -    struct ste_ssid *ste_ssid, *ste_rssid;
  95.227 -    ssidref_t ste_ssidref, ste_rssidref;
  95.228 -    struct domain *d, *rdom;
  95.229 -    domid_t rdomid;
  95.230 -    struct active_grant_entry *act;
  95.231 -    int port, i;
  95.232 -
  95.233 -    rcu_read_lock(&domlist_read_lock);
  95.234 -    read_lock(&ssid_list_rwlock);
  95.235 -
  95.236 -    /* go through all domains and adjust policy as if this domain was
  95.237 -       started now */
  95.238 -
  95.239 -    for_each_domain ( d )
  95.240 -    {
  95.241 -        struct evtchn *ports;
  95.242 -        unsigned int bucket;
  95.243 -
  95.244 -        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  95.245 -                             (struct acm_ssid_domain *)d->ssid);
  95.246 -        ste_ssidref = ste_ssid->ste_ssidref;
  95.247 -        traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n",
  95.248 -                    __func__, d->domain_id, ste_ssidref);
  95.249 -        /* a) check for event channel conflicts */
  95.250 -        for ( bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++ )
  95.251 -        {
  95.252 -            spin_lock(&d->evtchn_lock);
  95.253 -            ports = d->evtchn[bucket];
  95.254 -            if ( ports == NULL)
  95.255 -            {
  95.256 -                spin_unlock(&d->evtchn_lock);
  95.257 -                break;
  95.258 -            }
  95.259 -
  95.260 -            for ( port = 0; port < EVTCHNS_PER_BUCKET; port++ )
  95.261 -            {
  95.262 -                if ( ports[port].state == ECS_INTERDOMAIN )
  95.263 -                {
  95.264 -                    rdom = ports[port].u.interdomain.remote_dom;
  95.265 -                    rdomid = rdom->domain_id;
  95.266 -                } else {
  95.267 -                    continue; /* port unused */
  95.268 -                }
  95.269 -
  95.270 -                /* rdom now has remote domain */
  95.271 -                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
  95.272 -                                      (struct acm_ssid_domain *)(rdom->ssid));
  95.273 -                ste_rssidref = ste_rssid->ste_ssidref;
  95.274 -                traceprintk("%s: eventch: domain %x (ssidref %x) --> "
  95.275 -                            "domain %x (rssidref %x) used (port %x).\n",
  95.276 -                            __func__, d->domain_id, ste_ssidref,
  95.277 -                            rdom->domain_id, ste_rssidref, port);
  95.278 -                /* check whether on subj->ssid, obj->ssid share a common type*/
  95.279 -                if ( ! have_common_type(ste_ssidref, ste_rssidref) )
  95.280 -                {
  95.281 -                    printkd("%s: Policy violation in event channel domain "
  95.282 -                            "%x -> domain %x.\n",
  95.283 -                            __func__, d->domain_id, rdomid);
  95.284 -                    spin_unlock(&d->evtchn_lock);
  95.285 -
  95.286 -                    acm_array_append_tuple(errors,
  95.287 -                                           ACM_EVTCHN_SHARING_VIOLATION,
  95.288 -                                           d->domain_id << 16 | rdomid);
  95.289 -                    goto out;
  95.290 -                }
  95.291 -            }
  95.292 -            spin_unlock(&d->evtchn_lock);
  95.293 -        } 
  95.294 -
  95.295 -
  95.296 -        /* b) check for grant table conflicts on shared pages */
  95.297 -        spin_lock(&d->grant_table->lock);
  95.298 -        for ( i = 0; i < nr_active_grant_frames(d->grant_table); i++ )
  95.299 -        {
  95.300 -#define APP (PAGE_SIZE / sizeof(struct active_grant_entry))
  95.301 -            act = &d->grant_table->active[i/APP][i%APP];
  95.302 -            if ( act->pin != 0 ) {
  95.303 -                printkd("%s: grant dom (%hu) SHARED (%d) pin (%d)  "
  95.304 -                        "dom:(%hu) frame:(%lx)\n",
  95.305 -                        __func__, d->domain_id, i, act->pin,
  95.306 -                        act->domid, (unsigned long)act->frame);
  95.307 -                rdomid = act->domid;
  95.308 -                if ( (rdom = rcu_lock_domain_by_id(rdomid)) == NULL )
  95.309 -                {
  95.310 -                    spin_unlock(&d->grant_table->lock);
  95.311 -                    printkd("%s: domain not found ERROR!\n", __func__);
  95.312 -
  95.313 -                    acm_array_append_tuple(errors,
  95.314 -                                           ACM_DOMAIN_LOOKUP,
  95.315 -                                           rdomid);
  95.316 -                    goto out;
  95.317 -                }
  95.318 -                /* rdom now has remote domain */
  95.319 -                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
  95.320 -                                      (struct acm_ssid_domain *)(rdom->ssid));
  95.321 -                ste_rssidref = ste_rssid->ste_ssidref;
  95.322 -                rcu_unlock_domain(rdom);
  95.323 -                if ( ! have_common_type(ste_ssidref, ste_rssidref) )
  95.324 -                {
  95.325 -                    spin_unlock(&d->grant_table->lock);
  95.326 -                    printkd("%s: Policy violation in grant table "
  95.327 -                            "sharing domain %x -> domain %x.\n",
  95.328 -                            __func__, d->domain_id, rdomid);
  95.329 -
  95.330 -                    acm_array_append_tuple(errors,
  95.331 -                                           ACM_GNTTAB_SHARING_VIOLATION,
  95.332 -                                           d->domain_id << 16 | rdomid);
  95.333 -                    goto out;
  95.334 -                }
  95.335 -            }
  95.336 -        }
  95.337 -        spin_unlock(&d->grant_table->lock);
  95.338 -    }
  95.339 -    violation = 0;
  95.340 - out:
  95.341 -    read_unlock(&ssid_list_rwlock);
  95.342 -    rcu_read_unlock(&domlist_read_lock);
  95.343 -    return violation;
  95.344 -    /*
  95.345 -       returning "violation != 0" means that existing sharing between domains
  95.346 -       would not have been allowed if the new policy had been enforced before
  95.347 -       the sharing; for ste, this means that there are at least 2 domains
  95.348 -       that have established sharing through event-channels or grant-tables
  95.349 -       but these two domains don't have no longer a common type in their
  95.350 -       typesets referenced by their ssidrefs
  95.351 -      */
  95.352 -}
  95.353 -
  95.354 -
  95.355 -/*
  95.356 - * Call ste_init_state with the current policy.
  95.357 - */
  95.358 -int
  95.359 -do_ste_init_state_curr(struct acm_sized_buffer *errors)
  95.360 -{
  95.361 -    return ste_init_state(errors);
  95.362 -}
  95.363 -
  95.364 -
  95.365 -/* set new policy; policy write-locked already */
  95.366 -static int
  95.367 -_ste_update_policy(u8 *buf, u32 buf_size, int test_only,
  95.368 -                   struct acm_sized_buffer *errors)
  95.369 -{
  95.370 -    int rc = -EFAULT;
  95.371 -    struct acm_ste_policy_buffer *ste_buf =
  95.372 -                                 (struct acm_ste_policy_buffer *)buf;
  95.373 -    void *ssidrefsbuf;
  95.374 -    struct ste_ssid *ste_ssid;
  95.375 -    struct acm_ssid_domain *rawssid;
  95.376 -    int i;
  95.377 -
  95.378 -
  95.379 -    /* 1. create and copy-in new ssidrefs buffer */
  95.380 -    ssidrefsbuf = xmalloc_array(u8,
  95.381 -                                sizeof(domaintype_t) *
  95.382 -                                 ste_buf->ste_max_types *
  95.383 -                                 ste_buf->ste_max_ssidrefs);
  95.384 -    if ( ssidrefsbuf == NULL ) {
  95.385 -        return -ENOMEM;
  95.386 -    }
  95.387 -    if ( ste_buf->ste_ssid_offset +
  95.388 -         sizeof(domaintype_t) *
  95.389 -         ste_buf->ste_max_ssidrefs *
  95.390 -         ste_buf->ste_max_types > buf_size )
  95.391 -        goto error_free;
  95.392 -
  95.393 -    arrcpy(ssidrefsbuf, 
  95.394 -           buf + ste_buf->ste_ssid_offset,
  95.395 -           sizeof(domaintype_t),
  95.396 -           ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
  95.397 -
  95.398 -
  95.399 -    /*
  95.400 -     * 3. in test mode: re-calculate sharing decisions based on running
  95.401 -     *    domains; this can fail if new policy is conflicting with sharing
  95.402 -     *    of running domains
  95.403 -     *    now: reject violating new policy; future: adjust sharing through
  95.404 -     *    revoking sharing
  95.405 -     */
  95.406 -
  95.407 -    if ( test_only ) {
  95.408 -        /* temporarily replace old policy with new one for the testing */
  95.409 -        struct ste_binary_policy orig_ste_bin_pol = ste_bin_pol;
  95.410 -        ste_bin_pol.max_types = ste_buf->ste_max_types;
  95.411 -        ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
  95.412 -        ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
  95.413 -
  95.414 -        if ( ste_init_state(errors) )
  95.415 -        {
  95.416 -            /* new policy conflicts with sharing of running domains */
  95.417 -            printk("%s: New policy conflicts with running domains. "
  95.418 -                   "Policy load aborted.\n", __func__);
  95.419 -        } else {
  95.420 -            rc = ACM_OK;
  95.421 -        }
  95.422 -        /* revert changes, no matter whether testing was successful or not */
  95.423 -        ste_bin_pol = orig_ste_bin_pol;
  95.424 -        goto error_free;
  95.425 -    }
  95.426 -
  95.427 -    /* 3. replace old policy (activate new policy) */
  95.428 -    ste_bin_pol.max_types = ste_buf->ste_max_types;
  95.429 -    ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
  95.430 -    xfree(ste_bin_pol.ssidrefs);
  95.431 -    ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
  95.432 -
  95.433 -    /* clear all ste caches */
  95.434 -    read_lock(&ssid_list_rwlock);
  95.435 -
  95.436 -    for_each_acmssid( rawssid )
  95.437 -    {
  95.438 -        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid);
  95.439 -        for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
  95.440 -            ste_ssid->ste_cache[i].valid = ACM_STE_free;
  95.441 -    }
  95.442 -
  95.443 -    read_unlock(&ssid_list_rwlock);
  95.444 -
  95.445 -    return ACM_OK;
  95.446 -
  95.447 - error_free:
  95.448 -    if ( !test_only )
  95.449 -        printk("%s: ERROR setting policy.\n", __func__);
  95.450 -    xfree(ssidrefsbuf);
  95.451 -    return rc;
  95.452 -}
  95.453 -
  95.454 -static int
  95.455 -ste_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy,
  95.456 -                struct acm_sized_buffer *errors)
  95.457 -{
  95.458 -    struct acm_ste_policy_buffer *ste_buf =
  95.459 -             (struct acm_ste_policy_buffer *)buf;
  95.460 -
  95.461 -    if ( buf_size < sizeof(struct acm_ste_policy_buffer) )
  95.462 -        return -EINVAL;
  95.463 -
  95.464 -    /* Convert endianess of policy */
  95.465 -    ste_buf->policy_code = be32_to_cpu(ste_buf->policy_code);
  95.466 -    ste_buf->policy_version = be32_to_cpu(ste_buf->policy_version);
  95.467 -    ste_buf->ste_max_types = be32_to_cpu(ste_buf->ste_max_types);
  95.468 -    ste_buf->ste_max_ssidrefs = be32_to_cpu(ste_buf->ste_max_ssidrefs);
  95.469 -    ste_buf->ste_ssid_offset = be32_to_cpu(ste_buf->ste_ssid_offset);
  95.470 -
  95.471 -    /* policy type and version checks */
  95.472 -    if ( (ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ||
  95.473 -         (ste_buf->policy_version != ACM_STE_VERSION) )
  95.474 -        return -EINVAL;
  95.475 -
  95.476 -    /* during boot dom0_chwall_ssidref is set */
  95.477 -    if ( is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs) )
  95.478 -        return -EINVAL;
  95.479 -
  95.480 -    return _ste_update_policy(buf, buf_size, 1, errors);
  95.481 -}
  95.482 -
  95.483 -static int
  95.484 -ste_set_policy(u8 *buf, u32 buf_size)
  95.485 -{
  95.486 -    return _ste_update_policy(buf, buf_size, 0, NULL);
  95.487 -}
  95.488 -
  95.489 -static int 
  95.490 -ste_dump_stats(u8 *buf, u16 buf_len)
  95.491 -{
  95.492 -    struct acm_ste_stats_buffer stats;
  95.493 -
  95.494 -    /* now send the hook counts to user space */
  95.495 -    stats.ec_eval_count =
  95.496 -                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_eval_count));
  95.497 -    stats.gt_eval_count =
  95.498 -                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_eval_count));
  95.499 -    stats.ec_denied_count =
  95.500 -                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_denied_count));
  95.501 -    stats.gt_denied_count =
  95.502 -                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_denied_count));
  95.503 -    stats.ec_cachehit_count =
  95.504 -                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_cachehit_count));
  95.505 -    stats.gt_cachehit_count =
  95.506 -                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_cachehit_count));
  95.507 -
  95.508 -    if ( buf_len < sizeof(struct acm_ste_stats_buffer) )
  95.509 -        return -ENOMEM;
  95.510 -
  95.511 -    memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));
  95.512 -
  95.513 -    return sizeof(struct acm_ste_stats_buffer);
  95.514 -}
  95.515 -
  95.516 -static int
  95.517 -ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
  95.518 -{
  95.519 -    int i;
  95.520 -
  95.521 -    /* fill in buffer */
  95.522 -    if ( ste_bin_pol.max_types > len )
  95.523 -        return -EFAULT;
  95.524 -
  95.525 -    if ( ssidref >= ste_bin_pol.max_ssidrefs )
  95.526 -        return -EFAULT;
  95.527 -
  95.528 -    /* read types for chwall ssidref */
  95.529 -    for( i = 0; i< ste_bin_pol.max_types; i++ )
  95.530 -    {
  95.531 -        if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])
  95.532 -            buf[i] = 1;
  95.533 -        else
  95.534 -            buf[i] = 0;
  95.535 -    }
  95.536 -    return ste_bin_pol.max_types;
  95.537 -}
  95.538 -
  95.539 -/* we need to go through this before calling the hooks,
  95.540 - * returns 1 == cache hit */
  95.541 -static int inline
  95.542 -check_cache(struct domain *dom, domid_t rdom)
  95.543 -{
  95.544 -    struct ste_ssid *ste_ssid;
  95.545 -    int i;
  95.546 -
  95.547 -    printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
  95.548 -
  95.549 -    if (dom->ssid == NULL)
  95.550 -        return 0;
  95.551 -    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  95.552 -                         (struct acm_ssid_domain *)(dom->ssid));
  95.553 -
  95.554 -    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
  95.555 -    {
  95.556 -        if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
  95.557 -             (ste_ssid->ste_cache[i].id == rdom) )
  95.558 -        {
  95.559 -            printkd("cache hit (entry %x, id= %x!\n",
  95.560 -                    i,
  95.561 -                    ste_ssid->ste_cache[i].id);
  95.562 -            return 1;
  95.563 -        }
  95.564 -    }
  95.565 -    return 0;
  95.566 -}
  95.567 -
  95.568 -
  95.569 -/* we only get here if there is NO entry yet; no duplication check! */
  95.570 -static void inline
  95.571 -cache_result(struct domain *subj, struct domain *obj) {
  95.572 -    struct ste_ssid *ste_ssid;
  95.573 -    int i;
  95.574 -
  95.575 -    printkd("caching from doms: %x --> %x.\n",
  95.576 -            subj->domain_id, obj->domain_id);
  95.577 -
  95.578 -    if ( subj->ssid == NULL )
  95.579 -        return;
  95.580 -
  95.581 -    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  95.582 -                         (struct acm_ssid_domain *)(subj)->ssid);
  95.583 -
  95.584 -    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
  95.585 -        if ( ste_ssid->ste_cache[i].valid == ACM_STE_free )
  95.586 -            break;
  95.587 -    if ( i < ACM_TE_CACHE_SIZE )
  95.588 -    {
  95.589 -        ste_ssid->ste_cache[i].valid = ACM_STE_valid;
  95.590 -        ste_ssid->ste_cache[i].id = obj->domain_id;
  95.591 -    } else
  95.592 -        printk ("Cache of dom %x is full!\n", subj->domain_id);
  95.593 -}
  95.594 -
  95.595 -/* deletes entries for domain 'id' from all caches (re-use) */
  95.596 -static void inline
  95.597 -clean_id_from_cache(domid_t id) 
  95.598 -{
  95.599 -    struct ste_ssid *ste_ssid;
  95.600 -    int i;
  95.601 -    struct acm_ssid_domain *rawssid;
  95.602 -
  95.603 -    printkd("deleting cache for dom %x.\n", id);
  95.604 -
  95.605 -    read_lock(&ssid_list_rwlock);
  95.606 -    /* look through caches of all domains */
  95.607 -
  95.608 -    for_each_acmssid ( rawssid )
  95.609 -    {
  95.610 -        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid);
  95.611 -
  95.612 -        if ( !ste_ssid )
  95.613 -        {
  95.614 -            printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n",
  95.615 -                   __func__);
  95.616 -            goto out;
  95.617 -        }
  95.618 -        for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )
  95.619 -            if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
  95.620 -                 (ste_ssid->ste_cache[i].id == id) )
  95.621 -                ste_ssid->ste_cache[i].valid = ACM_STE_free;
  95.622 -    }
  95.623 -
  95.624 - out:
  95.625 -    read_unlock(&ssid_list_rwlock);
  95.626 -}
  95.627 -
  95.628 -/***************************
  95.629 - * Authorization functions
  95.630 - **************************/
  95.631 -static int 
  95.632 -ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
  95.633 -{      
  95.634 -    /* check for ssidref in range for policy */
  95.635 -    ssidref_t ste_ssidref;
  95.636 -
  95.637 -    traceprintk("%s.\n", __func__);
  95.638 -
  95.639 -    read_lock(&acm_bin_pol_rwlock);
  95.640 -
  95.641 -    ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
  95.642 -
  95.643 -    if ( ste_ssidref >= ste_bin_pol.max_ssidrefs )
  95.644 -    {
  95.645 -        printk("%s: ERROR ste_ssidref > max(%x).\n", 
  95.646 -               __func__, ste_bin_pol.max_ssidrefs-1);
  95.647 -        read_unlock(&acm_bin_pol_rwlock);
  95.648 -        return ACM_ACCESS_DENIED;
  95.649 -    }
  95.650 -
  95.651 -    read_unlock(&acm_bin_pol_rwlock);
  95.652 -
  95.653 -    return ACM_ACCESS_PERMITTED;
  95.654 -}
  95.655 -
  95.656 -static int
  95.657 -ste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t  domid)
  95.658 -{
  95.659 -    return ste_pre_domain_create(subject_ssid, ssidref);
  95.660 -}
  95.661 -
  95.662 -
  95.663 -static void 
  95.664 -ste_domain_destroy(void *subject_ssid, struct domain *d)
  95.665 -{
  95.666 -    /* clean all cache entries for destroyed domain (might be re-used) */
  95.667 -    clean_id_from_cache(d->domain_id);
  95.668 -}
  95.669 -
  95.670 -/* -------- EVENTCHANNEL OPERATIONS -----------*/
  95.671 -static int
  95.672 -ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) {
  95.673 -    struct domain *subj, *obj;
  95.674 -    int ret;
  95.675 -    traceprintk("%s: dom%x-->dom%x.\n", __func__,
  95.676 -                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
  95.677 -                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
  95.678 -
  95.679 -    if ( id1 == DOMID_SELF )
  95.680 -        id1 = current->domain->domain_id;
  95.681 -    if ( id2 == DOMID_SELF )
  95.682 -        id2 = current->domain->domain_id;
  95.683 -
  95.684 -    subj = rcu_lock_domain_by_id(id1);
  95.685 -    obj  = rcu_lock_domain_by_id(id2);
  95.686 -    if ( (subj == NULL) || (obj == NULL) )
  95.687 -    {
  95.688 -        ret = ACM_ACCESS_DENIED;
  95.689 -        goto out;
  95.690 -    }
  95.691 -    /* cache check late */
  95.692 -    if ( check_cache(subj, obj->domain_id) )
  95.693 -    {
  95.694 -        atomic_inc(&ste_bin_pol.ec_cachehit_count);
  95.695 -        ret = ACM_ACCESS_PERMITTED;
  95.696 -        goto out;
  95.697 -    }
  95.698 -    atomic_inc(&ste_bin_pol.ec_eval_count);
  95.699 -
  95.700 -    if ( share_common_type(subj, obj) )
  95.701 -    {
  95.702 -        cache_result(subj, obj);
  95.703 -        ret = ACM_ACCESS_PERMITTED;
  95.704 -    }
  95.705 -    else
  95.706 -    {
  95.707 -        atomic_inc(&ste_bin_pol.ec_denied_count);
  95.708 -        ret = ACM_ACCESS_DENIED;
  95.709 -    }
  95.710 -
  95.711 -  out:
  95.712 -    if ( obj != NULL )
  95.713 -        rcu_unlock_domain(obj);
  95.714 -    if ( subj != NULL )
  95.715 -        rcu_unlock_domain(subj);
  95.716 -    return ret;
  95.717 -}
  95.718 -
  95.719 -static int
  95.720 -ste_pre_eventchannel_interdomain(domid_t id)
  95.721 -{
  95.722 -    struct domain *subj=NULL, *obj=NULL;
  95.723 -    int ret;
  95.724 -
  95.725 -    traceprintk("%s: dom%x-->dom%x.\n", __func__,
  95.726 -                current->domain->domain_id,
  95.727 -                (id == DOMID_SELF) ? current->domain->domain_id : id);
  95.728 -
  95.729 -    /* following is a bit longer but ensures that we
  95.730 -     * "put" only domains that we where "find"-ing 
  95.731 -     */
  95.732 -    if ( id == DOMID_SELF )
  95.733 -        id = current->domain->domain_id;
  95.734 -
  95.735 -    subj = current->domain;
  95.736 -    obj  = rcu_lock_domain_by_id(id);
  95.737 -    if ( obj == NULL )
  95.738 -    {
  95.739 -        ret = ACM_ACCESS_DENIED;
  95.740 -        goto out;
  95.741 -    }
  95.742 -
  95.743 -    /* cache check late, but evtchn is not on performance critical path */
  95.744 -    if ( check_cache(subj, obj->domain_id) )
  95.745 -    {
  95.746 -        atomic_inc(&ste_bin_pol.ec_cachehit_count);
  95.747 -        ret = ACM_ACCESS_PERMITTED;
  95.748 -        goto out;
  95.749 -    }
  95.750 -
  95.751 -    atomic_inc(&ste_bin_pol.ec_eval_count);
  95.752 -
  95.753 -    if ( share_common_type(subj, obj) )
  95.754 -    {
  95.755 -        cache_result(subj, obj);
  95.756 -        ret = ACM_ACCESS_PERMITTED;
  95.757 -    }
  95.758 -    else
  95.759 -    {
  95.760 -        atomic_inc(&ste_bin_pol.ec_denied_count);
  95.761 -        ret = ACM_ACCESS_DENIED;
  95.762 -    }
  95.763 -
  95.764 - out:
  95.765 -    if ( obj != NULL )
  95.766 -        rcu_unlock_domain(obj);
  95.767 -    return ret;
  95.768 -}
  95.769 -
  95.770 -/* -------- SHARED MEMORY OPERATIONS -----------*/
  95.771 -
  95.772 -static int
  95.773 -ste_pre_grant_map_ref (domid_t id)
  95.774 -{
  95.775 -    struct domain *obj, *subj;
  95.776 -    int ret;
  95.777 -    traceprintk("%s: dom%x-->dom%x.\n", __func__,
  95.778 -                current->domain->domain_id, id);
  95.779 -
  95.780 -    if ( check_cache(current->domain, id) )
  95.781 -    {
  95.782 -        atomic_inc(&ste_bin_pol.gt_cachehit_count);
  95.783 -        return ACM_ACCESS_PERMITTED;
  95.784 -    }
  95.785 -    atomic_inc(&ste_bin_pol.gt_eval_count);
  95.786 -    subj = current->domain;
  95.787 -    obj = rcu_lock_domain_by_id(id);
  95.788 -
  95.789 -    if ( share_common_type(subj, obj) )
  95.790 -    {
  95.791 -        cache_result(subj, obj);
  95.792 -        ret = ACM_ACCESS_PERMITTED;
  95.793 -    }
  95.794 -    else
  95.795 -    {
  95.796 -        atomic_inc(&ste_bin_pol.gt_denied_count);
  95.797 -        printkd("%s: ACCESS DENIED!\n", __func__);
  95.798 -        ret = ACM_ACCESS_DENIED;
  95.799 -    }
  95.800 -    if ( obj != NULL )
  95.801 -        rcu_unlock_domain(obj);
  95.802 -    return ret;
  95.803 -}
  95.804 -
  95.805 -
  95.806 -/* since setting up grant tables involves some implicit information
  95.807 -   flow from the creating domain to the domain that is setup, we 
  95.808 -   check types in addition to the general authorization */
  95.809 -static int
  95.810 -ste_pre_grant_setup (domid_t id)
  95.811 -{
  95.812 -    struct domain *obj, *subj;
  95.813 -    int ret;
  95.814 -    traceprintk("%s: dom%x-->dom%x.\n", __func__,
  95.815 -                current->domain->domain_id, id);
  95.816 -
  95.817 -    if ( check_cache(current->domain, id) )
  95.818 -    {
  95.819 -        atomic_inc(&ste_bin_pol.gt_cachehit_count);
  95.820 -        return ACM_ACCESS_PERMITTED;
  95.821 -    }
  95.822 -    atomic_inc(&ste_bin_pol.gt_eval_count);
  95.823 -    /* a) check authorization (eventually use specific capabilities) */
  95.824 -    if ( !IS_PRIV(current->domain) )
  95.825 -    {
  95.826 -        printk("%s: Grant table management authorization denied ERROR!\n",
  95.827 -               __func__);
  95.828 -        return ACM_ACCESS_DENIED;
  95.829 -    }
  95.830 -    /* b) check types */
  95.831 -    subj = current->domain;
  95.832 -    obj = rcu_lock_domain_by_id(id);
  95.833 -
  95.834 -    if ( share_common_type(subj, obj) )
  95.835 -    {
  95.836 -        cache_result(subj, obj);
  95.837 -        ret = ACM_ACCESS_PERMITTED;
  95.838 -    }
  95.839 -    else
  95.840 -    {
  95.841 -        atomic_inc(&ste_bin_pol.gt_denied_count);
  95.842 -        ret = ACM_ACCESS_DENIED;
  95.843 -    }
  95.844 -    if ( obj != NULL )
  95.845 -        rcu_unlock_domain(obj);
  95.846 -    return ret;
  95.847 -}
  95.848 -
  95.849 -/* -------- DOMAIN-Requested Decision hooks -----------*/
  95.850 -
  95.851 -static int
  95.852 -ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
  95.853 -{
  95.854 -    int hct = have_common_type(
  95.855 -        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),
  95.856 -        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));
  95.857 -    return (hct ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);
  95.858 -}
  95.859 -
  95.860 -static int
  95.861 -ste_authorization(ssidref_t ssidref1, ssidref_t ssidref2)
  95.862 -{
  95.863 -    int iss = is_superset(
  95.864 -        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),
  95.865 -        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));
  95.866 -    return (iss ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);
  95.867 -}
  95.868 -
  95.869 -static int
  95.870 -ste_is_default_policy(void)
  95.871 -{
  95.872 -    return ((ste_bin_pol.max_types    == 1) &&
  95.873 -            (ste_bin_pol.max_ssidrefs == 2));
  95.874 -}
  95.875 -
  95.876 -/* now define the hook structure similarly to LSM */
  95.877 -struct acm_operations acm_simple_type_enforcement_ops = {
  95.878 -
  95.879 -    /* policy management services */
  95.880 -    .init_domain_ssid       = ste_init_domain_ssid,
  95.881 -    .free_domain_ssid       = ste_free_domain_ssid,
  95.882 -    .dump_binary_policy     = ste_dump_policy,
  95.883 -    .test_binary_policy     = ste_test_policy,
  95.884 -    .set_binary_policy      = ste_set_policy,
  95.885 -    .dump_statistics        = ste_dump_stats,
  95.886 -    .dump_ssid_types        = ste_dump_ssid_types,
  95.887 -
  95.888 -    /* domain management control hooks */
  95.889 -    .domain_create          = ste_domain_create,
  95.890 -    .domain_destroy         = ste_domain_destroy,
  95.891 -
  95.892 -    /* event channel control hooks */
  95.893 -    .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
  95.894 -    .fail_eventchannel_unbound = NULL,
  95.895 -    .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
  95.896 -    .fail_eventchannel_interdomain = NULL,
  95.897 -
  95.898 -    /* grant table control hooks */
  95.899 -    .pre_grant_map_ref      = ste_pre_grant_map_ref,
  95.900 -    .fail_grant_map_ref     = NULL,
  95.901 -    .pre_grant_setup        = ste_pre_grant_setup,
  95.902 -    .fail_grant_setup       = NULL,
  95.903 -    .sharing                = ste_sharing,
  95.904 -    .authorization          = ste_authorization,
  95.905 -
  95.906 -    .is_default_policy      = ste_is_default_policy,
  95.907 -};
  95.908 -
  95.909 -/*
  95.910 - * Local variables:
  95.911 - * mode: C
  95.912 - * c-set-style: "BSD"
  95.913 - * c-basic-offset: 4
  95.914 - * tab-width: 4
  95.915 - * indent-tabs-mode: nil
  95.916 - * End:
  95.917 - */
    96.1 --- a/xen/arch/ia64/xen/domain.c	Thu Sep 06 09:05:26 2007 -0600
    96.2 +++ b/xen/arch/ia64/xen/domain.c	Thu Sep 06 12:05:15 2007 -0600
    96.3 @@ -563,6 +563,7 @@ int arch_domain_create(struct domain *d)
    96.4  		goto fail_nomem;
    96.5  
    96.6  	memset(&d->arch.mm, 0, sizeof(d->arch.mm));
    96.7 +	d->arch.mm_teardown_offset = 0;
    96.8  
    96.9  	if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
   96.10  	    goto fail_nomem;
   96.11 @@ -936,14 +937,17 @@ static void relinquish_memory(struct dom
   96.12      spin_unlock_recursive(&d->page_alloc_lock);
   96.13  }
   96.14  
   96.15 -void domain_relinquish_resources(struct domain *d)
   96.16 +int domain_relinquish_resources(struct domain *d)
   96.17  {
   96.18 +    int ret;
   96.19      /* Relinquish guest resources for VT-i domain. */
   96.20      if (d->arch.is_vti)
   96.21  	    vmx_relinquish_guest_resources(d);
   96.22  
   96.23      /* Tear down shadow mode stuff. */
   96.24 -    mm_teardown(d);
   96.25 +    ret = mm_teardown(d);
   96.26 +    if (ret != 0)
   96.27 +        return ret;
   96.28  
   96.29      /* Relinquish every page of memory. */
   96.30      relinquish_memory(d, &d->xenpage_list);
   96.31 @@ -954,6 +958,8 @@ void domain_relinquish_resources(struct 
   96.32  
   96.33      /* Free page used by xen oprofile buffer */
   96.34      free_xenoprof_pages(d);
   96.35 +
   96.36 +    return 0;
   96.37  }
   96.38  
   96.39  unsigned long
    97.1 --- a/xen/arch/ia64/xen/mm.c	Thu Sep 06 09:05:26 2007 -0600
    97.2 +++ b/xen/arch/ia64/xen/mm.c	Thu Sep 06 12:05:15 2007 -0600
    97.3 @@ -215,6 +215,18 @@ alloc_dom_xen_and_dom_io(void)
    97.4      BUG_ON(dom_io == NULL);
    97.5  }
    97.6  
    97.7 +static int
    97.8 +mm_teardown_can_skip(struct domain* d, unsigned long offset)
    97.9 +{
   97.10 +    return d->arch.mm_teardown_offset > offset;
   97.11 +}
   97.12 +
   97.13 +static void
   97.14 +mm_teardown_update_offset(struct domain* d, unsigned long offset)
   97.15 +{
   97.16 +    d->arch.mm_teardown_offset = offset;
   97.17 +}
   97.18 +
   97.19  static void
   97.20  mm_teardown_pte(struct domain* d, volatile pte_t* pte, unsigned long offset)
   97.21  {
   97.22 @@ -252,46 +264,73 @@ mm_teardown_pte(struct domain* d, volati
   97.23      }
   97.24  }
   97.25  
   97.26 -static void
   97.27 +static int
   97.28  mm_teardown_pmd(struct domain* d, volatile pmd_t* pmd, unsigned long offset)
   97.29  {
   97.30      unsigned long i;
   97.31      volatile pte_t* pte = pte_offset_map(pmd, offset);
   97.32  
   97.33      for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
   97.34 -        if (!pte_present(*pte)) // acquire semantics
   97.35 +        unsigned long cur_offset = offset + (i << PAGE_SHIFT);
   97.36 +        if (mm_teardown_can_skip(d, cur_offset + PAGE_SIZE))
   97.37 +            continue;
   97.38 +        if (!pte_present(*pte)) { // acquire semantics
   97.39 +            mm_teardown_update_offset(d, cur_offset);
   97.40              continue;
   97.41 -        mm_teardown_pte(d, pte, offset + (i << PAGE_SHIFT));
   97.42 +        }
   97.43 +        mm_teardown_update_offset(d, cur_offset);
   97.44 +        mm_teardown_pte(d, pte, cur_offset);
   97.45 +        if (hypercall_preempt_check())
   97.46 +            return -EAGAIN;
   97.47      }
   97.48 +    return 0;
   97.49  }
   97.50  
   97.51 -static void
   97.52 +static int
   97.53  mm_teardown_pud(struct domain* d, volatile pud_t *pud, unsigned long offset)
   97.54  {
   97.55      unsigned long i;
   97.56      volatile pmd_t *pmd = pmd_offset(pud, offset);
   97.57  
   97.58      for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
   97.59 -        if (!pmd_present(*pmd)) // acquire semantics
   97.60 +        unsigned long cur_offset = offset + (i << PMD_SHIFT);
   97.61 +        if (mm_teardown_can_skip(d, cur_offset + PMD_SIZE))
   97.62 +            continue;
   97.63 +        if (!pmd_present(*pmd)) { // acquire semantics
   97.64 +            mm_teardown_update_offset(d, cur_offset);
   97.65              continue;
   97.66 -        mm_teardown_pmd(d, pmd, offset + (i << PMD_SHIFT));
   97.67 +        }
   97.68 +        if (mm_teardown_pmd(d, pmd, cur_offset))
   97.69 +            return -EAGAIN;
   97.70      }
   97.71 +    return 0;
   97.72  }
   97.73  
   97.74 -static void
   97.75 +static int
   97.76  mm_teardown_pgd(struct domain* d, volatile pgd_t *pgd, unsigned long offset)
   97.77  {
   97.78      unsigned long i;
   97.79      volatile pud_t *pud = pud_offset(pgd, offset);
   97.80  
   97.81      for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
   97.82 -        if (!pud_present(*pud)) // acquire semantics
   97.83 +        unsigned long cur_offset = offset + (i << PUD_SHIFT);
   97.84 +#ifndef __PAGETABLE_PUD_FOLDED
   97.85 +        if (mm_teardown_can_skip(d, cur_offset + PUD_SIZE))
   97.86              continue;
   97.87 -        mm_teardown_pud(d, pud, offset + (i << PUD_SHIFT));
   97.88 +#endif
   97.89 +        if (!pud_present(*pud)) { // acquire semantics
   97.90 +#ifndef __PAGETABLE_PUD_FOLDED
   97.91 +            mm_teardown_update_offset(d, cur_offset);
   97.92 +#endif
   97.93 +            continue;
   97.94 +        }
   97.95 +        if (mm_teardown_pud(d, pud, cur_offset))
   97.96 +            return -EAGAIN;
   97.97      }
   97.98 +    return 0;
   97.99  }
  97.100  
  97.101 -void
  97.102 +int
  97.103  mm_teardown(struct domain* d)
  97.104  {
  97.105      struct mm_struct* mm = &d->arch.mm;
    98.1 --- a/xen/arch/ia64/xen/xensetup.c	Thu Sep 06 09:05:26 2007 -0600
    98.2 +++ b/xen/arch/ia64/xen/xensetup.c	Thu Sep 06 12:05:15 2007 -0600
    98.3 @@ -28,7 +28,7 @@
    98.4  #include <asm/iosapic.h>
    98.5  #include <xen/softirq.h>
    98.6  #include <xen/rcupdate.h>
    98.7 -#include <acm/acm_hooks.h>
    98.8 +#include <xsm/acm/acm_hooks.h>
    98.9  #include <asm/sn/simulator.h>
   98.10  
   98.11  unsigned long xenheap_phys_end, total_pages;
    99.1 --- a/xen/arch/powerpc/domain.c	Thu Sep 06 09:05:26 2007 -0600
    99.2 +++ b/xen/arch/powerpc/domain.c	Thu Sep 06 12:05:15 2007 -0600
    99.3 @@ -313,13 +313,13 @@ static void relinquish_memory(struct dom
    99.4      spin_unlock_recursive(&d->page_alloc_lock);
    99.5  }
    99.6  
    99.7 -void domain_relinquish_resources(struct domain *d)
    99.8 +int domain_relinquish_resources(struct domain *d)
    99.9  {
   99.10      relinquish_memory(d, &d->xenpage_list);
   99.11      relinquish_memory(d, &d->page_list);
   99.12      xfree(d->arch.foreign_mfns);
   99.13      xfree(d->arch.p2m);
   99.14 -    return;
   99.15 +    return 0;
   99.16  }
   99.17  
   99.18  void arch_dump_domain_info(struct domain *d)
   100.1 --- a/xen/arch/powerpc/setup.c	Thu Sep 06 09:05:26 2007 -0600
   100.2 +++ b/xen/arch/powerpc/setup.c	Thu Sep 06 12:05:15 2007 -0600
   100.3 @@ -38,7 +38,7 @@
   100.4  #include <xen/numa.h>
   100.5  #include <xen/rcupdate.h>
   100.6  #include <xen/version.h>
   100.7 -#include <acm/acm_hooks.h>
   100.8 +#include <xsm/acm/acm_hooks.h>
   100.9  #include <public/version.h>
  100.10  #include <asm/mpic.h>
  100.11  #include <asm/processor.h>
   101.1 --- a/xen/arch/x86/cpu/Makefile	Thu Sep 06 09:05:26 2007 -0600
   101.2 +++ b/xen/arch/x86/cpu/Makefile	Thu Sep 06 12:05:15 2007 -0600
   101.3 @@ -8,5 +8,4 @@ obj-y += intel_cacheinfo.o
   101.4  
   101.5  obj-$(x86_32) += centaur.o
   101.6  obj-$(x86_32) += cyrix.o
   101.7 -obj-$(x86_32) += rise.o
   101.8  obj-$(x86_32) += transmeta.o
   102.1 --- a/xen/arch/x86/cpu/centaur.c	Thu Sep 06 09:05:26 2007 -0600
   102.2 +++ b/xen/arch/x86/cpu/centaur.c	Thu Sep 06 12:05:15 2007 -0600
   102.3 @@ -7,248 +7,6 @@
   102.4  #include <asm/e820.h>
   102.5  #include "cpu.h"
   102.6  
   102.7 -#ifdef CONFIG_X86_OOSTORE
   102.8 -
   102.9 -static u32 __init power2(u32 x)
  102.10 -{
  102.11 -	u32 s=1;
  102.12 -	while(s<=x)
  102.13 -		s<<=1;
  102.14 -	return s>>=1;
  102.15 -}
  102.16 -
  102.17 -
  102.18 -/*
  102.19 - *	Set up an actual MCR
  102.20 - */
  102.21 - 
  102.22 -static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key)
  102.23 -{
  102.24 -	u32 lo, hi;
  102.25 -	
  102.26 -	hi = base & ~0xFFF;
  102.27 -	lo = ~(size-1);		/* Size is a power of 2 so this makes a mask */
  102.28 -	lo &= ~0xFFF;		/* Remove the ctrl value bits */
  102.29 -	lo |= key;		/* Attribute we wish to set */
  102.30 -	wrmsr(reg+MSR_IDT_MCR0, lo, hi);
  102.31 -	mtrr_centaur_report_mcr(reg, lo, hi);	/* Tell the mtrr driver */
  102.32 -}
  102.33 -
  102.34 -/*
  102.35 - *	Figure what we can cover with MCR's
  102.36 - *
  102.37 - *	Shortcut: We know you can't put 4Gig of RAM on a winchip
  102.38 - */
  102.39 -
  102.40 -static u32 __init ramtop(void)		/* 16388 */
  102.41 -{
  102.42 -	int i;
  102.43 -	u32 top = 0;
  102.44 -	u32 clip = 0xFFFFFFFFUL;
  102.45 -	
  102.46 -	for (i = 0; i < e820.nr_map; i++) {
  102.47 -		unsigned long start, end;
  102.48 -
  102.49 -		if (e820.map[i].addr > 0xFFFFFFFFUL)
  102.50 -			continue;
  102.51 -		/*
  102.52 -		 *	Don't MCR over reserved space. Ignore the ISA hole
  102.53 -		 *	we frob around that catastrophy already
  102.54 -		 */
  102.55 -		 			
  102.56 -		if (e820.map[i].type == E820_RESERVED)
  102.57 -		{
  102.58 -			if(e820.map[i].addr >= 0x100000UL && e820.map[i].addr < clip)
  102.59 -				clip = e820.map[i].addr;
  102.60 -			continue;
  102.61 -		}
  102.62 -		start = e820.map[i].addr;
  102.63 -		end = e820.map[i].addr + e820.map[i].size;
  102.64 -		if (start >= end)
  102.65 -			continue;
  102.66 -		if (end > top)
  102.67 -			top = end;
  102.68 -	}
  102.69 -	/* Everything below 'top' should be RAM except for the ISA hole.
  102.70 -	   Because of the limited MCR's we want to map NV/ACPI into our
  102.71 -	   MCR range for gunk in RAM 
  102.72 -	   
  102.73 -	   Clip might cause us to MCR insufficient RAM but that is an
  102.74 -	   acceptable failure mode and should only bite obscure boxes with
  102.75 -	   a VESA hole at 15Mb
  102.76 -	   
  102.77 -	   The second case Clip sometimes kicks in is when the EBDA is marked
  102.78 -	   as reserved. Again we fail safe with reasonable results
  102.79 -	*/
  102.80 -	
  102.81 -	if(top>clip)
  102.82 -		top=clip;
  102.83 -		
  102.84 -	return top;
  102.85 -}
  102.86 -
  102.87 -/*
  102.88 - *	Compute a set of MCR's to give maximum coverage
  102.89 - */
  102.90 -
  102.91 -static int __init centaur_mcr_compute(int nr, int key)
  102.92 -{
  102.93 -	u32 mem = ramtop();
  102.94 -	u32 root = power2(mem);
  102.95 -	u32 base = root;
  102.96 -	u32 top = root;
  102.97 -	u32 floor = 0;
  102.98 -	int ct = 0;
  102.99 -	
 102.100 -	while(ct<nr)
 102.101 -	{
 102.102 -		u32 fspace = 0;
 102.103 -
 102.104 -		/*
 102.105 -		 *	Find the largest block we will fill going upwards
 102.106 -		 */
 102.107 -
 102.108 -		u32 high = power2(mem-top);	
 102.109 -
 102.110 -		/*
 102.111 -		 *	Find the largest block we will fill going downwards
 102.112 -		 */
 102.113 -
 102.114 -		u32 low = base/2;
 102.115 -
 102.116 -		/*
 102.117 -		 *	Don't fill below 1Mb going downwards as there
 102.118 -		 *	is an ISA hole in the way.
 102.119 -		 */		
 102.120 -		 
 102.121 -		if(base <= 1024*1024)
 102.122 -			low = 0;
 102.123 -			
 102.124 -		/*
 102.125 -		 *	See how much space we could cover by filling below
 102.126 -		 *	the ISA hole
 102.127 -		 */
 102.128 -		 
 102.129 -		if(floor == 0)
 102.130 -			fspace = 512*1024;
 102.131 -		else if(floor ==512*1024)
 102.132 -			fspace = 128*1024;
 102.133 -
 102.134 -		/* And forget ROM space */
 102.135 -		
 102.136 -		/*
 102.137 -		 *	Now install the largest coverage we get
 102.138 -		 */
 102.139 -		 
 102.140 -		if(fspace > high && fspace > low)
 102.141 -		{
 102.142 -			centaur_mcr_insert(ct, floor, fspace, key);
 102.143 -			floor += fspace;
 102.144 -		}
 102.145 -		else if(high > low)
 102.146 -		{
 102.147 -			centaur_mcr_insert(ct, top, high, key);
 102.148 -			top += high;
 102.149 -		}
 102.150 -		else if(low > 0)
 102.151 -		{
 102.152 -			base -= low;
 102.153 -			centaur_mcr_insert(ct, base, low, key);
 102.154 -		}
 102.155 -		else break;
 102.156 -		ct++;
 102.157 -	}
 102.158 -	/*
 102.159 -	 *	We loaded ct values. We now need to set the mask. The caller
 102.160 -	 *	must do this bit.
 102.161 -	 */
 102.162 -	 
 102.163 -	return ct;
 102.164 -}
 102.165 -
 102.166 -static void __init centaur_create_optimal_mcr(void)
 102.167 -{
 102.168 -	int i;
 102.169 -	/*
 102.170 -	 *	Allocate up to 6 mcrs to mark as much of ram as possible
 102.171 -	 *	as write combining and weak write ordered.
 102.172 -	 *
 102.173 -	 *	To experiment with: Linux never uses stack operations for 
 102.174 -	 *	mmio spaces so we could globally enable stack operation wc
 102.175 -	 *
 102.176 -	 *	Load the registers with type 31 - full write combining, all
 102.177 -	 *	writes weakly ordered.
 102.178 -	 */
 102.179 -	int used = centaur_mcr_compute(6, 31);
 102.180 -
 102.181 -	/*
 102.182 -	 *	Wipe unused MCRs
 102.183 -	 */
 102.184 -	 
 102.185 -	for(i=used;i<8;i++)
 102.186 -		wrmsr(MSR_IDT_MCR0+i, 0, 0);
 102.187 -}
 102.188 -
 102.189 -static void __init winchip2_create_optimal_mcr(void)
 102.190 -{
 102.191 -	u32 lo, hi;
 102.192 -	int i;
 102.193 -
 102.194 -	/*
 102.195 -	 *	Allocate up to 6 mcrs to mark as much of ram as possible
 102.196 -	 *	as write combining, weak store ordered.
 102.197 -	 *
 102.198 -	 *	Load the registers with type 25
 102.199 -	 *		8	-	weak write ordering
 102.200 -	 *		16	-	weak read ordering
 102.201 -	 *		1	-	write combining
 102.202 -	 */
 102.203 -
 102.204 -	int used = centaur_mcr_compute(6, 25);
 102.205 -	
 102.206 -	/*
 102.207 -	 *	Mark the registers we are using.
 102.208 -	 */
 102.209 -	 
 102.210 -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.211 -	for(i=0;i<used;i++)
 102.212 -		lo|=1<<(9+i);
 102.213 -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.214 -	
 102.215 -	/*
 102.216 -	 *	Wipe unused MCRs
 102.217 -	 */
 102.218 -	 
 102.219 -	for(i=used;i<8;i++)
 102.220 -		wrmsr(MSR_IDT_MCR0+i, 0, 0);
 102.221 -}
 102.222 -
 102.223 -/*
 102.224 - *	Handle the MCR key on the Winchip 2.
 102.225 - */
 102.226 -
 102.227 -static void __init winchip2_unprotect_mcr(void)
 102.228 -{
 102.229 -	u32 lo, hi;
 102.230 -	u32 key;
 102.231 -	
 102.232 -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.233 -	lo&=~0x1C0;	/* blank bits 8-6 */
 102.234 -	key = (lo>>17) & 7;
 102.235 -	lo |= key<<6;	/* replace with unlock key */
 102.236 -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.237 -}
 102.238 -
 102.239 -static void __init winchip2_protect_mcr(void)
 102.240 -{
 102.241 -	u32 lo, hi;
 102.242 -	
 102.243 -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.244 -	lo&=~0x1C0;	/* blank bits 8-6 */
 102.245 -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.246 -}
 102.247 -#endif /* CONFIG_X86_OOSTORE */
 102.248 -
 102.249  #define ACE_PRESENT	(1 << 6)
 102.250  #define ACE_ENABLED	(1 << 7)
 102.251  #define ACE_FCR		(1 << 28)	/* MSR_VIA_FCR */
 102.252 @@ -305,146 +63,12 @@ static void __init init_c3(struct cpuinf
 102.253  
 102.254  static void __init init_centaur(struct cpuinfo_x86 *c)
 102.255  {
 102.256 -	enum {
 102.257 -		ECX8=1<<1,
 102.258 -		EIERRINT=1<<2,
 102.259 -		DPM=1<<3,
 102.260 -		DMCE=1<<4,
 102.261 -		DSTPCLK=1<<5,
 102.262 -		ELINEAR=1<<6,
 102.263 -		DSMC=1<<7,
 102.264 -		DTLOCK=1<<8,
 102.265 -		EDCTLB=1<<8,
 102.266 -		EMMX=1<<9,
 102.267 -		DPDC=1<<11,
 102.268 -		EBRPRED=1<<12,
 102.269 -		DIC=1<<13,
 102.270 -		DDC=1<<14,
 102.271 -		DNA=1<<15,
 102.272 -		ERETSTK=1<<16,
 102.273 -		E2MMX=1<<19,
 102.274 -		EAMD3D=1<<20,
 102.275 -	};
 102.276 -
 102.277 -	char *name;
 102.278 -	u32  fcr_set=0;
 102.279 -	u32  fcr_clr=0;
 102.280 -	u32  lo,hi,newlo;
 102.281 -	u32  aa,bb,cc,dd;
 102.282 -
 102.283  	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
 102.284  	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
 102.285  	clear_bit(0*32+31, c->x86_capability);
 102.286  
 102.287 -	switch (c->x86) {
 102.288 -
 102.289 -		case 5:
 102.290 -			switch(c->x86_model) {
 102.291 -			case 4:
 102.292 -				name="C6";
 102.293 -				fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
 102.294 -				fcr_clr=DPDC;
 102.295 -				printk(KERN_NOTICE "Disabling bugged TSC.\n");
 102.296 -				clear_bit(X86_FEATURE_TSC, c->x86_capability);
 102.297 -#ifdef CONFIG_X86_OOSTORE
 102.298 -				centaur_create_optimal_mcr();
 102.299 -				/* Enable
 102.300 -					write combining on non-stack, non-string
 102.301 -					write combining on string, all types
 102.302 -					weak write ordering 
 102.303 -					
 102.304 -				   The C6 original lacks weak read order 
 102.305 -				   
 102.306 -				   Note 0x120 is write only on Winchip 1 */
 102.307 -				   
 102.308 -				wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);
 102.309 -#endif				
 102.310 -				break;
 102.311 -			case 8:
 102.312 -				switch(c->x86_mask) {
 102.313 -				default:
 102.314 -					name="2";
 102.315 -					break;
 102.316 -				case 7 ... 9:
 102.317 -					name="2A";
 102.318 -					break;
 102.319 -				case 10 ... 15:
 102.320 -					name="2B";
 102.321 -					break;
 102.322 -				}
 102.323 -				fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D;
 102.324 -				fcr_clr=DPDC;
 102.325 -#ifdef CONFIG_X86_OOSTORE
 102.326 -				winchip2_unprotect_mcr();
 102.327 -				winchip2_create_optimal_mcr();
 102.328 -				rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.329 -				/* Enable
 102.330 -					write combining on non-stack, non-string
 102.331 -					write combining on string, all types
 102.332 -					weak write ordering 
 102.333 -				*/
 102.334 -				lo|=31;				
 102.335 -				wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.336 -				winchip2_protect_mcr();
 102.337 -#endif
 102.338 -				break;
 102.339 -			case 9:
 102.340 -				name="3";
 102.341 -				fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D;
 102.342 -				fcr_clr=DPDC;
 102.343 -#ifdef CONFIG_X86_OOSTORE
 102.344 -				winchip2_unprotect_mcr();
 102.345 -				winchip2_create_optimal_mcr();
 102.346 -				rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.347 -				/* Enable
 102.348 -					write combining on non-stack, non-string
 102.349 -					write combining on string, all types
 102.350 -					weak write ordering 
 102.351 -				*/
 102.352 -				lo|=31;				
 102.353 -				wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 102.354 -				winchip2_protect_mcr();
 102.355 -#endif
 102.356 -				break;
 102.357 -			case 10:
 102.358 -				name="4";
 102.359 -				/* no info on the WC4 yet */
 102.360 -				break;
 102.361 -			default:
 102.362 -				name="??";
 102.363 -			}
 102.364 -
 102.365 -			rdmsr(MSR_IDT_FCR1, lo, hi);
 102.366 -			newlo=(lo|fcr_set) & (~fcr_clr);
 102.367 -
 102.368 -			if (newlo!=lo) {
 102.369 -				printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo );
 102.370 -				wrmsr(MSR_IDT_FCR1, newlo, hi );
 102.371 -			} else {
 102.372 -				printk(KERN_INFO "Centaur FCR is 0x%X\n",lo);
 102.373 -			}
 102.374 -			/* Emulate MTRRs using Centaur's MCR. */
 102.375 -			set_bit(X86_FEATURE_CENTAUR_MCR, c->x86_capability);
 102.376 -			/* Report CX8 */
 102.377 -			set_bit(X86_FEATURE_CX8, c->x86_capability);
 102.378 -			/* Set 3DNow! on Winchip 2 and above. */
 102.379 -			if (c->x86_model >=8)
 102.380 -				set_bit(X86_FEATURE_3DNOW, c->x86_capability);
 102.381 -			/* See if we can find out some more. */
 102.382 -			if ( cpuid_eax(0x80000000) >= 0x80000005 ) {
 102.383 -				/* Yes, we can. */
 102.384 -				cpuid(0x80000005,&aa,&bb,&cc,&dd);
 102.385 -				/* Add L1 data and code cache sizes. */
 102.386 -				c->x86_cache_size = (cc>>24)+(dd>>24);
 102.387 -			}
 102.388 -			snprintf( c->x86_model_id, sizeof(c->x86_model_id),
 102.389 -				"WinChip %s", name );
 102.390 -			break;
 102.391 -
 102.392 -		case 6:
 102.393 -			init_c3(c);
 102.394 -			break;
 102.395 -	}
 102.396 +	if (c->x86 == 6)
 102.397 +		init_c3(c);
 102.398  }
 102.399  
 102.400  static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size)
   103.1 --- a/xen/arch/x86/cpu/common.c	Thu Sep 06 09:05:26 2007 -0600
   103.2 +++ b/xen/arch/x86/cpu/common.c	Thu Sep 06 12:05:15 2007 -0600
   103.3 @@ -524,7 +524,6 @@ extern int nsc_init_cpu(void);
   103.4  extern int amd_init_cpu(void);
   103.5  extern int centaur_init_cpu(void);
   103.6  extern int transmeta_init_cpu(void);
   103.7 -extern int rise_init_cpu(void);
   103.8  
   103.9  void __init early_cpu_init(void)
  103.10  {
  103.11 @@ -535,7 +534,6 @@ void __init early_cpu_init(void)
  103.12  	nsc_init_cpu();
  103.13  	centaur_init_cpu();
  103.14  	transmeta_init_cpu();
  103.15 -	rise_init_cpu();
  103.16  #endif
  103.17  	early_cpu_detect();
  103.18  }
   104.1 --- a/xen/arch/x86/cpu/mtrr/Makefile	Thu Sep 06 09:05:26 2007 -0600
   104.2 +++ b/xen/arch/x86/cpu/mtrr/Makefile	Thu Sep 06 12:05:15 2007 -0600
   104.3 @@ -1,5 +1,4 @@
   104.4  obj-$(x86_32) += amd.o
   104.5 -obj-$(x86_32) += centaur.o
   104.6  obj-$(x86_32) += cyrix.o
   104.7  obj-y += generic.o
   104.8  obj-y += main.o
   105.1 --- a/xen/arch/x86/cpu/mtrr/centaur.c	Thu Sep 06 09:05:26 2007 -0600
   105.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.3 @@ -1,223 +0,0 @@
   105.4 -#include <xen/init.h>
   105.5 -#include <xen/mm.h>
   105.6 -#include <asm/mtrr.h>
   105.7 -#include <asm/msr.h>
   105.8 -#include "mtrr.h"
   105.9 -
  105.10 -static struct {
  105.11 -	unsigned long high;
  105.12 -	unsigned long low;
  105.13 -} centaur_mcr[8];
  105.14 -
  105.15 -static u8 centaur_mcr_reserved;
  105.16 -static u8 centaur_mcr_type;	/* 0 for winchip, 1 for winchip2 */
  105.17 -
  105.18 -/*
  105.19 - *	Report boot time MCR setups 
  105.20 - */
  105.21 -
  105.22 -static int
  105.23 -centaur_get_free_region(unsigned long base, unsigned long size)
  105.24 -/*  [SUMMARY] Get a free MTRR.
  105.25 -    <base> The starting (base) address of the region.
  105.26 -    <size> The size (in bytes) of the region.
  105.27 -    [RETURNS] The index of the region on success, else -1 on error.
  105.28 -*/
  105.29 -{
  105.30 -	int i, max;
  105.31 -	mtrr_type ltype;
  105.32 -	unsigned long lbase;
  105.33 -	unsigned int lsize;
  105.34 -
  105.35 -	max = num_var_ranges;
  105.36 -	for (i = 0; i < max; ++i) {
  105.37 -		if (centaur_mcr_reserved & (1 << i))
  105.38 -			continue;
  105.39 -		mtrr_if->get(i, &lbase, &lsize, &ltype);
  105.40 -		if (lsize == 0)
  105.41 -			return i;
  105.42 -	}
  105.43 -	return -ENOSPC;
  105.44 -}
  105.45 -
  105.46 -void
  105.47 -mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
  105.48 -{
  105.49 -	centaur_mcr[mcr].low = lo;
  105.50 -	centaur_mcr[mcr].high = hi;
  105.51 -}
  105.52 -
  105.53 -static void
  105.54 -centaur_get_mcr(unsigned int reg, unsigned long *base,
  105.55 -		unsigned int *size, mtrr_type * type)
  105.56 -{
  105.57 -	*base = centaur_mcr[reg].high >> PAGE_SHIFT;
  105.58 -	*size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
  105.59 -	*type = MTRR_TYPE_WRCOMB;	/*  If it is there, it is write-combining  */
  105.60 -	if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2))
  105.61 -		*type = MTRR_TYPE_UNCACHABLE;
  105.62 -	if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25)
  105.63 -		*type = MTRR_TYPE_WRBACK;
  105.64 -	if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31)
  105.65 -		*type = MTRR_TYPE_WRBACK;
  105.66 -
  105.67 -}
  105.68 -
  105.69 -static void centaur_set_mcr(unsigned int reg, unsigned long base,
  105.70 -			    unsigned long size, mtrr_type type)
  105.71 -{
  105.72 -	unsigned long low, high;
  105.73 -
  105.74 -	if (size == 0) {
  105.75 -		/*  Disable  */
  105.76 -		high = low = 0;
  105.77 -	} else {
  105.78 -		high = base << PAGE_SHIFT;
  105.79 -		if (centaur_mcr_type == 0)
  105.80 -			low = -size << PAGE_SHIFT | 0x1f;	/* only support write-combining... */
  105.81 -		else {
  105.82 -			if (type == MTRR_TYPE_UNCACHABLE)
  105.83 -				low = -size << PAGE_SHIFT | 0x02;	/* NC */
  105.84 -			else
  105.85 -				low = -size << PAGE_SHIFT | 0x09;	/* WWO,WC */
  105.86 -		}
  105.87 -	}
  105.88 -	centaur_mcr[reg].high = high;
  105.89 -	centaur_mcr[reg].low = low;
  105.90 -	wrmsr(MSR_IDT_MCR0 + reg, low, high);
  105.91 -}
  105.92 -
  105.93 -#if 0
  105.94 -/*
  105.95 - *	Initialise the later (saner) Winchip MCR variant. In this version
  105.96 - *	the BIOS can pass us the registers it has used (but not their values)
  105.97 - *	and the control register is read/write
  105.98 - */
  105.99 -
 105.100 -static void __init
 105.101 -centaur_mcr1_init(void)
 105.102 -{
 105.103 -	unsigned i;
 105.104 -	u32 lo, hi;
 105.105 -
 105.106 -	/* Unfortunately, MCR's are read-only, so there is no way to
 105.107 -	 * find out what the bios might have done.
 105.108 -	 */
 105.109 -
 105.110 -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
 105.111 -	if (((lo >> 17) & 7) == 1) {	/* Type 1 Winchip2 MCR */
 105.112 -		lo &= ~0x1C0;	/* clear key */
 105.113 -		lo |= 0x040;	/* set key to 1 */
 105.114 -		wrmsr(MSR_IDT_MCR_CTRL, lo, hi);	/* unlock MCR */
 105.115 -	}
 105.116 -
 105.117 -	centaur_mcr_type = 1;
 105.118 -
 105.119 -	/*
 105.120 -	 *  Clear any unconfigured MCR's.
 105.121 -	 */
 105.122 -
 105.123 -	for (i = 0; i < 8; ++i) {
 105.124 -		if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) {
 105.125 -			if (!(lo & (1 << (9 + i))))
 105.126 -				wrmsr(MSR_IDT_MCR0 + i, 0, 0);
 105.127 -			else
 105.128 -				/*
 105.129 -				 *      If the BIOS set up an MCR we cannot see it
 105.130 -				 *      but we don't wish to obliterate it
 105.131 -				 */
 105.132 -				centaur_mcr_reserved |= (1 << i);
 105.133 -		}
 105.134 -	}
 105.135 -	/*  
 105.136 -	 *  Throw the main write-combining switch... 
 105.137 -	 *  However if OOSTORE is enabled then people have already done far
 105.138 -	 *  cleverer things and we should behave. 
 105.139 -	 */
 105.140 -
 105.141 -	lo |= 15;		/* Write combine enables */
 105.142 -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 105.143 -}
 105.144 -
 105.145 -/*
 105.146 - *	Initialise the original winchip with read only MCR registers
 105.147 - *	no used bitmask for the BIOS to pass on and write only control
 105.148 - */
 105.149 -
 105.150 -static void __init
 105.151 -centaur_mcr0_init(void)
 105.152 -{
 105.153 -	unsigned i;
 105.154 -
 105.155 -	/* Unfortunately, MCR's are read-only, so there is no way to
 105.156 -	 * find out what the bios might have done.
 105.157 -	 */
 105.158 -
 105.159 -	/* Clear any unconfigured MCR's.
 105.160 -	 * This way we are sure that the centaur_mcr array contains the actual
 105.161 -	 * values. The disadvantage is that any BIOS tweaks are thus undone.
 105.162 -	 *
 105.163 -	 */
 105.164 -	for (i = 0; i < 8; ++i) {
 105.165 -		if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0)
 105.166 -			wrmsr(MSR_IDT_MCR0 + i, 0, 0);
 105.167 -	}
 105.168 -
 105.169 -	wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);	/* Write only */
 105.170 -}
 105.171 -
 105.172 -/*
 105.173 - *	Initialise Winchip series MCR registers
 105.174 - */
 105.175 -
 105.176 -static void __init
 105.177 -centaur_mcr_init(void)
 105.178 -{
 105.179 -	struct set_mtrr_context ctxt;
 105.180 -
 105.181 -	set_mtrr_prepare_save(&ctxt);
 105.182 -	set_mtrr_cache_disable(&ctxt);
 105.183 -
 105.184 -	if (boot_cpu_data.x86_model == 4)
 105.185 -		centaur_mcr0_init();
 105.186 -	else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9)
 105.187 -		centaur_mcr1_init();
 105.188 -
 105.189 -	set_mtrr_done(&ctxt);
 105.190 -}
 105.191 -#endif
 105.192 -
 105.193 -static int centaur_validate_add_page(unsigned long base, 
 105.194 -				     unsigned long size, unsigned int type)
 105.195 -{
 105.196 -	/*
 105.197 -	 *  FIXME: Winchip2 supports uncached
 105.198 -	 */
 105.199 -	if (type != MTRR_TYPE_WRCOMB && 
 105.200 -	    (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
 105.201 -		printk(KERN_WARNING
 105.202 -		       "mtrr: only write-combining%s supported\n",
 105.203 -		       centaur_mcr_type ? " and uncacheable are"
 105.204 -		       : " is");
 105.205 -		return -EINVAL;
 105.206 -	}
 105.207 -	return 0;
 105.208 -}
 105.209 -
 105.210 -static struct mtrr_ops centaur_mtrr_ops = {
 105.211 -	.vendor            = X86_VENDOR_CENTAUR,
 105.212 -//	.init              = centaur_mcr_init,
 105.213 -	.set               = centaur_set_mcr,
 105.214 -	.get               = centaur_get_mcr,
 105.215 -	.get_free_region   = centaur_get_free_region,
 105.216 -	.validate_add_page = centaur_validate_add_page,
 105.217 -	.have_wrcomb       = positive_have_wrcomb,
 105.218 -};
 105.219 -
 105.220 -int __init centaur_init_mtrr(void)
 105.221 -{
 105.222 -	set_mtrr_ops(&centaur_mtrr_ops);
 105.223 -	return 0;
 105.224 -}
 105.225 -
 105.226 -//arch_initcall(centaur_init_mtrr);
   106.1 --- a/xen/arch/x86/cpu/mtrr/main.c	Thu Sep 06 09:05:26 2007 -0600
   106.2 +++ b/xen/arch/x86/cpu/mtrr/main.c	Thu Sep 06 12:05:15 2007 -0600
   106.3 @@ -539,14 +539,12 @@ EXPORT_SYMBOL(mtrr_del);
   106.4   */
   106.5  extern void amd_init_mtrr(void);
   106.6  extern void cyrix_init_mtrr(void);
   106.7 -extern void centaur_init_mtrr(void);
   106.8  
   106.9  static void __init init_ifs(void)
  106.10  {
  106.11  #ifndef CONFIG_X86_64
  106.12  	amd_init_mtrr();
  106.13  	cyrix_init_mtrr();
  106.14 -	centaur_init_mtrr();
  106.15  #endif
  106.16  }
  106.17  
  106.18 @@ -609,13 +607,6 @@ void __init mtrr_bp_init(void)
  106.19  				size_and_mask = 0;
  106.20  			}
  106.21  			break;
  106.22 -		case X86_VENDOR_CENTAUR:
  106.23 -			if (cpu_has_centaur_mcr) {
  106.24 -				mtrr_if = mtrr_ops[X86_VENDOR_CENTAUR];
  106.25 -				size_or_mask = 0xfff00000;	/* 32 bits */
  106.26 -				size_and_mask = 0;
  106.27 -			}
  106.28 -			break;
  106.29  		case X86_VENDOR_CYRIX:
  106.30  			if (cpu_has_cyrix_arr) {
  106.31  				mtrr_if = mtrr_ops[X86_VENDOR_CYRIX];
   107.1 --- a/xen/arch/x86/cpu/rise.c	Thu Sep 06 09:05:26 2007 -0600
   107.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.3 @@ -1,54 +0,0 @@
   107.4 -#include <xen/config.h>
   107.5 -#include <xen/lib.h>
   107.6 -#include <xen/init.h>
   107.7 -#include <xen/bitops.h>
   107.8 -#include <asm/processor.h>
   107.9 -
  107.10 -#include "cpu.h"
  107.11 -
  107.12 -static void __init init_rise(struct cpuinfo_x86 *c)
  107.13 -{
  107.14 -	printk("CPU: Rise iDragon");
  107.15 -	if (c->x86_model > 2)
  107.16 -		printk(" II");
  107.17 -	printk("\n");
  107.18 -
  107.19 -	/* Unhide possibly hidden capability flags
  107.20 -	   The mp6 iDragon family don't have MSRs.
  107.21 -	   We switch on extra features with this cpuid weirdness: */
  107.22 -	__asm__ (
  107.23 -		"movl $0x6363452a, %%eax\n\t"
  107.24 -		"movl $0x3231206c, %%ecx\n\t"
  107.25 -		"movl $0x2a32313a, %%edx\n\t"
  107.26 -		"cpuid\n\t"
  107.27 -		"movl $0x63634523, %%eax\n\t"
  107.28 -		"movl $0x32315f6c, %%ecx\n\t"
  107.29 -		"movl $0x2333313a, %%edx\n\t"
  107.30 -		"cpuid\n\t" : : : "eax", "ebx", "ecx", "edx"
  107.31 -	);
  107.32 -	set_bit(X86_FEATURE_CX8, c->x86_capability);
  107.33 -}
  107.34 -
  107.35 -static struct cpu_dev rise_cpu_dev __initdata = {
  107.36 -	.c_vendor	= "Rise",
  107.37 -	.c_ident	= { "RiseRiseRise" },
  107.38 -	.c_models = {
  107.39 -		{ .vendor = X86_VENDOR_RISE, .family = 5, .model_names = 
  107.40 -		  { 
  107.41 -			  [0] = "iDragon", 
  107.42 -			  [2] = "iDragon", 
  107.43 -			  [8] = "iDragon II", 
  107.44 -			  [9] = "iDragon II"
  107.45 -		  }
  107.46 -		},
  107.47 -	},
  107.48 -	.c_init		= init_rise,
  107.49 -};
  107.50 -
  107.51 -int __init rise_init_cpu(void)
  107.52 -{
  107.53 -	cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev;
  107.54 -	return 0;
  107.55 -}
  107.56 -
  107.57 -//early_arch_initcall(rise_init_cpu);
   108.1 --- a/xen/arch/x86/domain.c	Thu Sep 06 09:05:26 2007 -0600
   108.2 +++ b/xen/arch/x86/domain.c	Thu Sep 06 12:05:15 2007 -0600
   108.3 @@ -437,6 +437,9 @@ int arch_domain_create(struct domain *d)
   108.4      int vcpuid, pdpt_order, paging_initialised = 0;
   108.5      int rc = -ENOMEM;
   108.6  
   108.7 +    d->arch.relmem = RELMEM_not_started;
   108.8 +    INIT_LIST_HEAD(&d->arch.relmem_list);
   108.9 +
  108.10      pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
  108.11      d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
  108.12      if ( d->arch.mm_perdomain_pt == NULL )
  108.13 @@ -1599,12 +1602,13 @@ int hypercall_xlat_continuation(unsigned
  108.14  }
  108.15  #endif
  108.16  
  108.17 -static void relinquish_memory(struct domain *d, struct list_head *list,
  108.18 -                              unsigned long type)
  108.19 +static int relinquish_memory(
  108.20 +    struct domain *d, struct list_head *list, unsigned long type)
  108.21  {
  108.22      struct list_head *ent;
  108.23      struct page_info  *page;
  108.24      unsigned long     x, y;
  108.25 +    int               ret = 0;
  108.26  
  108.27      /* Use a recursive lock, as we may enter 'free_domheap_page'. */
  108.28      spin_lock_recursive(&d->page_alloc_lock);
  108.29 @@ -1619,6 +1623,7 @@ static void relinquish_memory(struct dom
  108.30          {
  108.31              /* Couldn't get a reference -- someone is freeing this page. */
  108.32              ent = ent->next;
  108.33 +            list_move_tail(&page->list, &d->arch.relmem_list);
  108.34              continue;
  108.35          }
  108.36  
  108.37 @@ -1653,10 +1658,21 @@ static void relinquish_memory(struct dom
  108.38  
  108.39          /* Follow the list chain and /then/ potentially free the page. */
  108.40          ent = ent->next;
  108.41 +        list_move_tail(&page->list, &d->arch.relmem_list);
  108.42          put_page(page);
  108.43 +
  108.44 +        if ( hypercall_preempt_check() )
  108.45 +        {
  108.46 +            ret = -EAGAIN;
  108.47 +            goto out;
  108.48 +        }
  108.49      }
  108.50  
  108.51 +    list_splice_init(&d->arch.relmem_list, list);
  108.52 +
  108.53 + out:
  108.54      spin_unlock_recursive(&d->page_alloc_lock);
  108.55 +    return ret;
  108.56  }
  108.57  
  108.58  static void vcpu_destroy_pagetables(struct vcpu *v)
  108.59 @@ -1717,43 +1733,91 @@ static void vcpu_destroy_pagetables(stru
  108.60      v->arch.cr3 = 0;
  108.61  }
  108.62  
  108.63 -void domain_relinquish_resources(struct domain *d)
  108.64 +int domain_relinquish_resources(struct domain *d)
  108.65  {
  108.66 +    int ret;
  108.67      struct vcpu *v;
  108.68  
  108.69      BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
  108.70  
  108.71 -    /* Drop the in-use references to page-table bases. */
  108.72 -    for_each_vcpu ( d, v )
  108.73 -        vcpu_destroy_pagetables(v);
  108.74 +    switch ( d->arch.relmem )
  108.75 +    {
  108.76 +    case RELMEM_not_started:
  108.77 +        /* Tear down paging-assistance stuff. */
  108.78 +        paging_teardown(d);
  108.79 +
  108.80 +        /* Drop the in-use references to page-table bases. */
  108.81 +        for_each_vcpu ( d, v )
  108.82 +            vcpu_destroy_pagetables(v);
  108.83  
  108.84 -    /* Tear down paging-assistance stuff. */
  108.85 -    paging_teardown(d);
  108.86 +        /*
  108.87 +         * Relinquish GDT mappings. No need for explicit unmapping of the LDT
  108.88 +         * as it automatically gets squashed when the guest's mappings go away.
  108.89 +         */
  108.90 +        for_each_vcpu(d, v)
  108.91 +            destroy_gdt(v);
  108.92 +
  108.93 +        d->arch.relmem = RELMEM_xen_l4;
  108.94 +        /* fallthrough */
  108.95  
  108.96 -    /*
  108.97 -     * Relinquish GDT mappings. No need for explicit unmapping of the LDT as
  108.98 -     * it automatically gets squashed when the guest's mappings go away.
  108.99 -     */
 108.100 -    for_each_vcpu(d, v)
 108.101 -        destroy_gdt(v);
 108.102 -
 108.103 -    /* Relinquish every page of memory. */
 108.104 +        /* Relinquish every page of memory. */
 108.105  #if CONFIG_PAGING_LEVELS >= 4
 108.106 -    relinquish_memory(d, &d->xenpage_list, PGT_l4_page_table);
 108.107 -    relinquish_memory(d, &d->page_list, PGT_l4_page_table);
 108.108 +    case RELMEM_xen_l4:
 108.109 +        ret = relinquish_memory(d, &d->xenpage_list, PGT_l4_page_table);
 108.110 +        if ( ret )
 108.111 +            return ret;
 108.112 +        d->arch.relmem = RELMEM_dom_l4;
 108.113 +        /* fallthrough */
 108.114 +	case RELMEM_dom_l4:
 108.115 +        ret = relinquish_memory(d, &d->page_list, PGT_l4_page_table);
 108.116 +        if ( ret )
 108.117 +            return ret;
 108.118 +        d->arch.relmem = RELMEM_xen_l3;
 108.119 +        /* fallthrough */
 108.120  #endif
 108.121 +
 108.122  #if CONFIG_PAGING_LEVELS >= 3
 108.123 -    relinquish_memory(d, &d->xenpage_list, PGT_l3_page_table);
 108.124 -    relinquish_memory(d, &d->page_list, PGT_l3_page_table);
 108.125 +	case RELMEM_xen_l3:
 108.126 +        ret = relinquish_memory(d, &d->xenpage_list, PGT_l3_page_table);
 108.127 +        if ( ret )
 108.128 +            return ret;
 108.129 +        d->arch.relmem = RELMEM_dom_l3;
 108.130 +        /* fallthrough */
 108.131 +	case RELMEM_dom_l3:
 108.132 +        ret = relinquish_memory(d, &d->page_list, PGT_l3_page_table);
 108.133 +        if ( ret )
 108.134 +            return ret;
 108.135 +        d->arch.relmem = RELMEM_xen_l2;
 108.136 +        /* fallthrough */
 108.137  #endif
 108.138 -    relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table);
 108.139 -    relinquish_memory(d, &d->page_list, PGT_l2_page_table);
 108.140 +
 108.141 +	case RELMEM_xen_l2:
 108.142 +        ret = relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table);
 108.143 +        if ( ret )
 108.144 +            return ret;
 108.145 +        d->arch.relmem = RELMEM_dom_l2;
 108.146 +        /* fallthrough */
 108.147 +	case RELMEM_dom_l2:
 108.148 +        ret = relinquish_memory(d, &d->page_list, PGT_l2_page_table);
 108.149 +        if ( ret )
 108.150 +            return ret;
 108.151 +        d->arch.relmem = RELMEM_done;
 108.152 +        /* fallthrough */
 108.153 +
 108.154 +	case RELMEM_done:
 108.155 +        break;
 108.156 +
 108.157 +    default:
 108.158 +        BUG();
 108.159 +    }
 108.160  
 108.161      /* Free page used by xen oprofile buffer. */
 108.162      free_xenoprof_pages(d);
 108.163  
 108.164      if ( is_hvm_domain(d) )
 108.165          hvm_domain_relinquish_resources(d);
 108.166 +
 108.167 +    return 0;
 108.168  }
 108.169  
 108.170  void arch_dump_domain_info(struct domain *d)
   109.1 --- a/xen/arch/x86/domain_build.c	Thu Sep 06 09:05:26 2007 -0600
   109.2 +++ b/xen/arch/x86/domain_build.c	Thu Sep 06 12:05:15 2007 -0600
   109.3 @@ -26,6 +26,7 @@
   109.4  #include <asm/desc.h>
   109.5  #include <asm/i387.h>
   109.6  #include <asm/paging.h>
   109.7 +#include <asm/e820.h>
   109.8  
   109.9  #include <public/version.h>
  109.10  #include <public/libelf.h>
  109.11 @@ -989,6 +990,16 @@ int __init construct_dom0(
  109.12              rc |= iomem_deny_access(dom0, mfn, mfn);
  109.13      }
  109.14  
  109.15 +    /* Remove access to E820_UNUSABLE I/O regions. */
  109.16 +    for ( i = 0; i < e820.nr_map; i++ )
  109.17 +    {
  109.18 +        if ( e820.map[i].type != E820_UNUSABLE)
  109.19 +            continue;
  109.20 +        mfn = paddr_to_pfn(e820.map[i].addr);
  109.21 +        nr_pages = (e820.map[i].size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  109.22 +        rc |= iomem_deny_access(dom0, mfn, mfn + nr_pages - 1);
  109.23 +    }
  109.24 +
  109.25      BUG_ON(rc != 0);
  109.26  
  109.27      return 0;
   110.1 --- a/xen/arch/x86/domctl.c	Thu Sep 06 09:05:26 2007 -0600
   110.2 +++ b/xen/arch/x86/domctl.c	Thu Sep 06 12:05:15 2007 -0600
   110.3 @@ -24,6 +24,7 @@
   110.4  #include <asm/hvm/hvm.h>
   110.5  #include <asm/hvm/support.h>
   110.6  #include <asm/processor.h>
   110.7 +#include <xsm/xsm.h>
   110.8  
   110.9  long arch_do_domctl(
  110.10      struct xen_domctl *domctl,
  110.11 @@ -64,6 +65,14 @@ long arch_do_domctl(
  110.12          if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) )
  110.13              break;
  110.14  
  110.15 +        ret = xsm_ioport_permission(d, fp, 
  110.16 +                                    domctl->u.ioport_permission.allow_access);
  110.17 +        if ( ret )
  110.18 +        {
  110.19 +            rcu_unlock_domain(d);
  110.20 +            break;
  110.21 +        }
  110.22 +
  110.23          if ( np == 0 )
  110.24              ret = 0;
  110.25          else if ( domctl->u.ioport_permission.allow_access )
  110.26 @@ -90,6 +99,13 @@ long arch_do_domctl(
  110.27  
  110.28          page = mfn_to_page(mfn);
  110.29  
  110.30 +        ret = xsm_getpageframeinfo(page);
  110.31 +        if ( ret )
  110.32 +        {
  110.33 +            rcu_unlock_domain(d);
  110.34 +            break;
  110.35 +        }
  110.36 +
  110.37          if ( likely(get_page(page, d)) )
  110.38          {
  110.39              ret = 0;
  110.40 @@ -173,6 +189,10 @@ long arch_do_domctl(
  110.41  
  110.42                  page = mfn_to_page(mfn);
  110.43  
  110.44 +                ret = xsm_getpageframeinfo(page);
  110.45 +                if ( ret )
  110.46 +                    continue;
  110.47 +
  110.48                  if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 
  110.49                  {
  110.50                      unsigned long type = 0;
  110.51 @@ -230,10 +250,21 @@ long arch_do_domctl(
  110.52          ret = -EINVAL;
  110.53          if ( d != NULL )
  110.54          {
  110.55 -            ret = 0;
  110.56 +            ret = xsm_getmemlist(d);
  110.57 +            if ( ret )
  110.58 +            {
  110.59 +                rcu_unlock_domain(d);
  110.60 +                break;
  110.61 +            }
  110.62  
  110.63              spin_lock(&d->page_alloc_lock);
  110.64  
  110.65 +            if ( unlikely(d->is_dying) ) {
  110.66 +                spin_unlock(&d->page_alloc_lock);
  110.67 +                goto getmemlist_out;
  110.68 +            }
  110.69 +
  110.70 +            ret = 0;
  110.71              list_ent = d->page_list.next;
  110.72              for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
  110.73              {
  110.74 @@ -252,7 +283,7 @@ long arch_do_domctl(
  110.75  
  110.76              domctl->u.getmemlist.num_pfns = i;
  110.77              copy_to_guest(u_domctl, domctl, 1);
  110.78 -
  110.79 +        getmemlist_out:
  110.80              rcu_unlock_domain(d);
  110.81          }
  110.82      }
  110.83 @@ -269,6 +300,13 @@ long arch_do_domctl(
  110.84          if ( unlikely(d == NULL) )