diff --git a/Config.mk b/Config.mk index 7bed4b8fe8..3b24b07abe 100644 --- a/Config.mk +++ b/Config.mk @@ -44,13 +44,21 @@ CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i)) # Choose the best mirror to download linux kernel KERNEL_REPO = http://www.kernel.org -# ACM_USE_SECURITY_POLICY is set to security policy of Xen +# If ACM_SECURITY = y, then the access control module is compiled +# into Xen and the policy type can be set by the boot policy file +# y - Build the Xen ACM framework +# n - Do not build the Xen ACM framework +ACM_SECURITY ?= n + +# If ACM_SECURITY = y and no boot policy file is installed, +# then the ACM defaults to the security policy set by +# ACM_DEFAULT_SECURITY_POLICY # Supported models are: -# ACM_NULL_POLICY (ACM will not be built with this policy) +# ACM_NULL_POLICY # ACM_CHINESE_WALL_POLICY # ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY # ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY -ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY +ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY # Optional components XENSTAT_XENTOP ?= y diff --git a/tools/security/Makefile b/tools/security/Makefile index ca77c2c81c..0d95a9b93f 100644 --- a/tools/security/Makefile +++ b/tools/security/Makefile @@ -12,21 +12,21 @@ CFLAGS_XML2BIN += $(shell xml2-config --cflags --libs ) XML2VERSION = $(shell xml2-config --version ) VALIDATE_SCHEMA=$(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else echo "-DVALIDATE_SCHEMA"; fi; ) -ifeq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY) +ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_NULL_POLICY) POLICY=null endif -ifeq ($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_POLICY) +ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_POLICY) POLICY=chwall endif -ifeq ($(ACM_USE_SECURITY_POLICY),ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) +ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) POLICY=ste endif -ifeq ($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) +ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) POLICY=chwall_ste endif POLICYFILE=./policies/$(POLICY)/$(POLICY).bin -ifneq ($(ACM_USE_SECURITY_POLICY), ACM_NULL_POLICY) +ifeq ($(ACM_SECURITY),y) all: build install:all @@ -55,7 +55,7 @@ secpol_xml2bin : secpol_xml2bin.c secpol_xml2bin.h $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_XML2BIN) $(VALIDATE_SCHEMA) -o $@ $< clean: - rm -rf secpol_tool secpol_xml2bin xen + rm -rf secpol_tool secpol_xml2bin xen get_decision policy_clean: rm -rf policies/*/*.bin policies/*/*.map diff --git a/tools/security/install.txt b/tools/security/install.txt index e915617155..e67a7d6fe6 100644 --- a/tools/security/install.txt +++ b/tools/security/install.txt @@ -24,11 +24,13 @@ exclusively (chwall_ste --> {chwall, ste}). # cd "xen_root" # edit/xemacs/vi Config.mk - change the line: - ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY + change the lines: + ACM_SECURITY ?= n + ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY to: - ACM_USE_SECURITY_POLICY ?= ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY + ACM_SECURITY ?= y + ACM_DEFAULT_SECURITY_POLICY ?= ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY # make all # ./install.sh diff --git a/xen/Makefile b/xen/Makefile index d3a0bfd04d..07d63bb57c 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -57,7 +57,7 @@ $(TARGET): delete-unfresh-files $(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h $(MAKE) -C common $(MAKE) -C drivers -ifneq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY) +ifeq ($(ACM_SECURITY),y) $(MAKE) -C acm endif $(MAKE) -C arch/$(TARGET_ARCH) @@ -79,8 +79,8 @@ include/xen/acm_policy.h: echo " *"; \ echo " */"; \ echo ""; \ - echo "#ifndef ACM_USE_SECURITY_POLICY"; \ - echo "#define ACM_USE_SECURITY_POLICY $(ACM_USE_SECURITY_POLICY)"; \ + echo "#ifndef ACM_DEFAULT_SECURITY_POLICY"; \ + echo "#define ACM_DEFAULT_SECURITY_POLICY $(ACM_DEFAULT_SECURITY_POLICY)"; \ echo "#endif") >$@ # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. diff --git a/xen/Rules.mk b/xen/Rules.mk index 484130c861..0f43b4efa9 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -37,8 +37,9 @@ OBJS += $(patsubst %.c,%.o,$(C_SRCS)) ALL_OBJS := $(BASEDIR)/common/common.o ALL_OBJS += $(BASEDIR)/drivers/char/driver.o ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o -ifneq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY) +ifeq ($(ACM_SECURITY),y) ALL_OBJS += $(BASEDIR)/acm/acm.o +CFLAGS += -DACM_SECURITY endif ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o diff --git a/xen/acm/acm_core.c b/xen/acm/acm_core.c index 456f186b7a..2e85abf38d 100644 --- a/xen/acm/acm_core.c +++ b/xen/acm/acm_core.c @@ -49,6 +49,9 @@ void acm_init_ste_policy(void); extern struct acm_operations acm_chinesewall_ops, acm_simple_type_enforcement_ops, acm_null_ops; +/* global ACM policy (now dynamically determined at boot time) */ +u16 acm_active_security_policy = ACM_POLICY_UNDEFINED; + /* global ops structs called by the hooks */ struct acm_operations *acm_primary_ops = NULL; /* called in hook if-and-only-if primary succeeds */ @@ -61,7 +64,8 @@ rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED; /* until we have endian support in Xen, we discover it at runtime */ u8 little_endian = 1; -void acm_set_endian(void) +void +acm_set_endian(void) { u32 test = 1; if (*((u8 *)&test) == 1) @@ -76,14 +80,82 @@ void acm_set_endian(void) } } -/* initialize global security policy for Xen; policy write-locked already */ -static void -acm_init_binary_policy(void *primary, void *secondary) +int +acm_init_binary_policy(u32 policy_code) { - acm_bin_pol.primary_policy_code = 0; - acm_bin_pol.secondary_policy_code = 0; - acm_bin_pol.primary_binary_policy = primary; - acm_bin_pol.secondary_binary_policy = secondary; + int ret = ACM_OK; + + acm_bin_pol.primary_policy_code = (policy_code & 0x0f); + acm_bin_pol.secondary_policy_code = (policy_code >> 4) & 0x0f; + + write_lock(&acm_bin_pol_rwlock); + + /* set primary policy component */ + switch ((policy_code) & 0x0f) + { + + case ACM_CHINESE_WALL_POLICY: + acm_init_chwall_policy(); + acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; + acm_primary_ops = &acm_chinesewall_ops; + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + acm_init_ste_policy(); + acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_primary_ops = &acm_simple_type_enforcement_ops; + break; + + case ACM_NULL_POLICY: + acm_bin_pol.primary_policy_code = ACM_NULL_POLICY; + acm_primary_ops = &acm_null_ops; + break; + + default: + /* Unknown policy not allowed primary */ + ret = -EINVAL; + goto out; + } + + /* secondary policy component part */ + switch ((policy_code) >> 4) + { + + case ACM_NULL_POLICY: + acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; + acm_secondary_ops = &acm_null_ops; + break; + + case ACM_CHINESE_WALL_POLICY: + if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY) + { /* not a valid combination */ + ret = -EINVAL; + goto out; + } + acm_init_chwall_policy(); + acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY; + acm_secondary_ops = &acm_chinesewall_ops; + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + if (acm_bin_pol.primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + { /* not a valid combination */ + ret = -EINVAL; + goto out; + } + acm_init_ste_policy(); + acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_secondary_ops = &acm_simple_type_enforcement_ops; + break; + + default: + ret = -EINVAL; + goto out; + } + + out: + write_unlock(&acm_bin_pol_rwlock); + return ret; } static int @@ -161,83 +233,35 @@ acm_init(unsigned int *initrdidx, int ret = ACM_OK; acm_set_endian(); - write_lock(&acm_bin_pol_rwlock); - acm_init_binary_policy(NULL, NULL); - /* set primary policy component */ - switch ((ACM_USE_SECURITY_POLICY) & 0x0f) + /* first try to load the boot policy (uses its own locks) */ + acm_setup(initrdidx, mbi, initial_images_start); + + if (acm_active_security_policy != ACM_POLICY_UNDEFINED) { + printk("%s: Boot-Policy. Enforcing %s: Primary %s, Secondary %s.\n", __func__, + ACM_POLICY_NAME(acm_active_security_policy), + ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), + ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); + goto out; + } + /* else continue with the minimal hardcoded default startup policy */ + printk("%s: Loading default policy (%s).\n", + __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY)); - case ACM_CHINESE_WALL_POLICY: - acm_init_chwall_policy(); - acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_primary_ops = &acm_chinesewall_ops; - break; - - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - acm_init_ste_policy(); - acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_primary_ops = &acm_simple_type_enforcement_ops; - break; - - default: - /* NULL or Unknown policy not allowed primary; - * NULL/NULL will not compile this code */ - ret = -EINVAL; - goto out; - } - - /* secondary policy component part */ - switch ((ACM_USE_SECURITY_POLICY) >> 4) { - case ACM_NULL_POLICY: - acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; - acm_secondary_ops = &acm_null_ops; - break; - - case ACM_CHINESE_WALL_POLICY: - if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY) - { /* not a valid combination */ - ret = -EINVAL; - goto out; - } - acm_init_chwall_policy(); - acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_secondary_ops = &acm_chinesewall_ops; - break; - - case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: - if (acm_bin_pol.primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) - { /* not a valid combination */ - ret = -EINVAL; - goto out; - } - acm_init_ste_policy(); - acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_secondary_ops = &acm_simple_type_enforcement_ops; - break; - - default: + if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) { ret = -EINVAL; goto out; } + acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY; out: - write_unlock(&acm_bin_pol_rwlock); - if (ret != ACM_OK) { printk("%s: Error initializing policies.\n", __func__); /* here one could imagine a clean panic */ return -EINVAL; } - if (acm_setup(initrdidx, mbi, initial_images_start) != ACM_OK) - { - printk("%s: Error loading policy at boot time.\n", __func__); - /* ignore, just continue with the minimal hardcoded startup policy */ - } - printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, - ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), - ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); return ret; } @@ -265,7 +289,7 @@ acm_init_domain_ssid(domid_t id, ssidref_t ssidref) ssid->primary_ssid = NULL; ssid->secondary_ssid = NULL; - if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) + if (acm_active_security_policy != ACM_NULL_POLICY) ssid->ssidref = ssidref; else ssid->ssidref = ACM_DEFAULT_SSID; diff --git a/xen/acm/acm_policy.c b/xen/acm/acm_policy.c index e316370993..a581f7d723 100644 --- a/xen/acm/acm_policy.c +++ b/xen/acm/acm_policy.c @@ -56,17 +56,29 @@ acm_set_policy(void *buf, u32 buf_size, int isuserbuffer) /* 2. some sanity checking */ pol = (struct acm_policy_buffer *)policy_buffer; - if ((ntohl(pol->magic) != ACM_MAGIC) || - (ntohl(pol->policy_version) != ACM_POLICY_VERSION) || - (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || - (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) + if ((ntohl(pol->magic) != ACM_MAGIC) || + (buf_size != ntohl(pol->len)) || + (ntohl(pol->policy_version) != ACM_POLICY_VERSION)) { - printkd("%s: Wrong policy magics or versions!\n", __func__); + printk("%s: ERROR in Magic, Version, or buf size.\n", __func__); goto error_free; } - if (buf_size != ntohl(pol->len)) + + if (acm_active_security_policy == ACM_POLICY_UNDEFINED) { + /* setup the policy with the boot policy */ + if (acm_init_binary_policy((ntohl(pol->secondary_policy_code) << 4) | + ntohl(pol->primary_policy_code))) { + goto error_free; + } + acm_active_security_policy = + (acm_bin_pol.secondary_policy_code << 4) | acm_bin_pol.primary_policy_code; + } + + /* once acm_active_security_policy is set, it cannot be changed */ + if ((ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || + (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) { - printk("%s: ERROR in buf size.\n", __func__); + printkd("%s: Wrong policy type in boot policy!\n", __func__); goto error_free; } diff --git a/xen/common/acm_ops.c b/xen/common/acm_ops.c index d290b40de6..1d19674a4c 100644 --- a/xen/common/acm_ops.c +++ b/xen/common/acm_ops.c @@ -29,7 +29,7 @@ #include #include -#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) +#ifndef ACM_SECURITY long do_acm_op(struct acm_op * u_acm_op) { diff --git a/xen/include/acm/acm_core.h b/xen/include/acm/acm_core.h index eaa46ee3d5..7733192ad3 100644 --- a/xen/include/acm/acm_core.h +++ b/xen/include/acm/acm_core.h @@ -28,9 +28,6 @@ struct acm_binary_policy { u16 primary_policy_code; u16 secondary_policy_code; - void *primary_binary_policy; - void *secondary_binary_policy; - }; struct chwall_binary_policy { @@ -53,6 +50,7 @@ struct ste_binary_policy { }; /* global acm policy */ +extern u16 acm_active_security_policy; extern struct acm_binary_policy acm_bin_pol; extern struct chwall_binary_policy chwall_bin_pol; extern struct ste_binary_policy ste_bin_pol; @@ -120,6 +118,7 @@ struct ste_ssid { /* protos */ int acm_init_domain_ssid(domid_t id, ssidref_t ssidref); void acm_free_domain_ssid(struct acm_ssid_domain *ssid); +int acm_init_binary_policy(u32 policy_code); int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer); int acm_get_policy(void *buf, u32 buf_size); int acm_dump_statistics(void *buf, u16 buf_size); diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h index 011669373d..8208ef153a 100644 --- a/xen/include/acm/acm_hooks.h +++ b/xen/include/acm/acm_hooks.h @@ -127,7 +127,7 @@ extern struct acm_operations *acm_secondary_ops; # define traceprintk(fmt, args...) #endif -#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) +#ifndef ACM_SECURITY static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) { return 0; } diff --git a/xen/include/public/acm.h b/xen/include/public/acm.h index a6646c3792..3db340a00d 100644 --- a/xen/include/public/acm.h +++ b/xen/include/public/acm.h @@ -60,6 +60,7 @@ #define ACM_NULL_POLICY 0 #define ACM_CHINESE_WALL_POLICY 1 #define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2 +#define ACM_POLICY_UNDEFINED 15 /* combinations have secondary policy component in higher 4bit */ #define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \