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, <ype); 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(¢aur_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) )