diff options
author | Keir Fraser <keir@xen.org> | 2011-03-25 21:47:57 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-03-25 21:47:57 +0000 |
commit | 6102cace934c5ef156e7e1e21966cf3950dc40e5 (patch) | |
tree | 612c892c08a8a6c371b3c02981b2699e7ebdc9ae /xen | |
parent | 662f524483de23084ae4dde930fa7570fb15e033 (diff) | |
download | xen-6102cace934c5ef156e7e1e21966cf3950dc40e5.tar.gz xen-6102cace934c5ef156e7e1e21966cf3950dc40e5.tar.bz2 xen-6102cace934c5ef156e7e1e21966cf3950dc40e5.zip |
Remove unmaintained Access Control Module (ACM) from hypervisor.
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen')
-rw-r--r-- | xen/Rules.mk | 1 | ||||
-rw-r--r-- | xen/arch/ia64/xen/xensetup.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 3 | ||||
-rw-r--r-- | xen/common/domain.c | 2 | ||||
-rw-r--r-- | xen/include/public/xsm/acm.h | 223 | ||||
-rw-r--r-- | xen/include/public/xsm/acm_ops.h | 159 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 3 | ||||
-rw-r--r-- | xen/include/xsm/acm/acm_core.h | 197 | ||||
-rw-r--r-- | xen/include/xsm/acm/acm_endian.h | 69 | ||||
-rw-r--r-- | xen/include/xsm/acm/acm_hooks.h | 374 | ||||
-rw-r--r-- | xen/xsm/Makefile | 1 | ||||
-rw-r--r-- | xen/xsm/acm/Makefile | 7 | ||||
-rw-r--r-- | xen/xsm/acm/acm_chinesewall_hooks.c | 721 | ||||
-rw-r--r-- | xen/xsm/acm/acm_core.c | 406 | ||||
-rw-r--r-- | xen/xsm/acm/acm_null_hooks.c | 95 | ||||
-rw-r--r-- | xen/xsm/acm/acm_ops.c | 212 | ||||
-rw-r--r-- | xen/xsm/acm/acm_policy.c | 893 | ||||
-rw-r--r-- | xen/xsm/acm/acm_simple_type_enforcement_hooks.c | 924 | ||||
-rw-r--r-- | xen/xsm/acm/acm_xsm_hooks.c | 74 | ||||
-rw-r--r-- | xen/xsm/xsm_policy.c | 1 |
20 files changed, 4 insertions, 4364 deletions
diff --git a/xen/Rules.mk b/xen/Rules.mk index e9d9c89850..f48ac56326 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -45,7 +45,6 @@ CFLAGS-y += -g -D__XEN__ CFLAGS-$(XSM_ENABLE) += -DXSM_ENABLE CFLAGS-$(FLASK_ENABLE) += -DFLASK_ENABLE -DXSM_MAGIC=0xf97cff8c CFLAGS-$(FLASK_ENABLE) += -DFLASK_DEVELOP -DFLASK_BOOTPARAM -DFLASK_AVC_STATS -CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY -DXSM_MAGIC=0xbcde0100 CFLAGS-$(verbose) += -DVERBOSE CFLAGS-$(crash_debug) += -DCRASH_DEBUG CFLAGS-$(perfc) += -DPERF_COUNTERS diff --git a/xen/arch/ia64/xen/xensetup.c b/xen/arch/ia64/xen/xensetup.c index be2550d22b..7b053a59a5 100644 --- a/xen/arch/ia64/xen/xensetup.c +++ b/xen/arch/ia64/xen/xensetup.c @@ -29,7 +29,6 @@ #include <asm/iosapic.h> #include <xen/softirq.h> #include <xen/rcupdate.h> -#include <xsm/acm/acm_hooks.h> #include <asm/sn/simulator.h> #include <asm/sal.h> #include <xen/cpu.h> @@ -645,7 +644,7 @@ printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus); expose_p2m_init(); /* Create initial domain 0. */ - dom0 = domain_create(0, 0, DOM0_SSIDREF); + dom0 = domain_create(0, 0, 0); if (dom0 == NULL) panic("Error creating domain 0\n"); domain_set_vhpt_size(dom0, dom0_vhpt_size_log2); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 5734782d76..0478079dbc 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -36,7 +36,6 @@ #include <asm/desc.h> #include <asm/paging.h> #include <asm/e820.h> -#include <xsm/acm/acm_hooks.h> #include <xen/kexec.h> #include <asm/edd.h> #include <xsm/xsm.h> @@ -1266,7 +1265,7 @@ void __init __start_xen(unsigned long mbi_p) panic("Could not protect TXT memory regions\n"); /* Create initial domain 0. */ - dom0 = domain_create(0, DOMCRF_s3_integrity, DOM0_SSIDREF); + dom0 = domain_create(0, DOMCRF_s3_integrity, 0); if ( (dom0 == NULL) || (alloc_dom0_vcpu0() == NULL) ) panic("Error creating domain 0\n"); diff --git a/xen/common/domain.c b/xen/common/domain.c index b8c48a7ab0..51aa0400df 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -212,7 +212,7 @@ static void __init parse_extra_guest_irqs(const char *s) custom_param("extra_guest_irqs", parse_extra_guest_irqs); struct domain *domain_create( - domid_t domid, unsigned int domcr_flags, ssidref_t ssidref) + domid_t domid, unsigned int domcr_flags, uint32_t ssidref) { struct domain *d, **pd; enum { INIT_xsm = 1u<<0, INIT_watchdog = 1u<<1, INIT_rangeset = 1u<<2, diff --git a/xen/include/public/xsm/acm.h b/xen/include/public/xsm/acm.h deleted file mode 100644 index b6ac8d5130..0000000000 --- a/xen/include/public/xsm/acm.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * acm.h: Xen access control module interface defintions - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Reiner Sailer <sailer@watson.ibm.com> - * Copyright (c) 2005, International Business Machines Corporation. - */ - -#ifndef _XEN_PUBLIC_ACM_H -#define _XEN_PUBLIC_ACM_H - -#include "../xen.h" - -/* default ssid reference value if not supplied */ -#define ACM_DEFAULT_SSID 0x0 -#define ACM_DEFAULT_LOCAL_SSID 0x0 - -/* Internal ACM ERROR types */ -#define ACM_OK 0 -#define ACM_UNDEF -1 -#define ACM_INIT_SSID_ERROR -2 -#define ACM_INIT_SOID_ERROR -3 -#define ACM_ERROR -4 - -/* External ACCESS DECISIONS */ -#define ACM_ACCESS_PERMITTED 0 -#define ACM_ACCESS_DENIED -111 -#define ACM_NULL_POINTER_ERROR -200 - -/* - Error codes reported in when trying to test for a new policy - These error codes are reported in an array of tuples where - each error code is followed by a parameter describing the error - more closely, such as a domain id. -*/ -#define ACM_EVTCHN_SHARING_VIOLATION 0x100 -#define ACM_GNTTAB_SHARING_VIOLATION 0x101 -#define ACM_DOMAIN_LOOKUP 0x102 -#define ACM_CHWALL_CONFLICT 0x103 -#define ACM_SSIDREF_IN_USE 0x104 - - -/* primary policy in lower 4 bits */ -#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 \ - ((ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY << 4) | ACM_CHINESE_WALL_POLICY) - -/* policy: */ -#define ACM_POLICY_NAME(X) \ - ((X) == (ACM_NULL_POLICY)) ? "NULL" : \ - ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL" : \ - ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT" : \ - ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT" : \ - "UNDEFINED" - -/* the following policy versions must be increased - * whenever the interpretation of the related - * policy's data structure changes - */ -#define ACM_POLICY_VERSION 4 -#define ACM_CHWALL_VERSION 1 -#define ACM_STE_VERSION 1 - -/* defines a ssid reference used by xen */ -typedef uint32_t ssidref_t; - -/* hooks that are known to domains */ -#define ACMHOOK_none 0 -#define ACMHOOK_sharing 1 -#define ACMHOOK_authorization 2 -#define ACMHOOK_conflictset 3 - -/* -------security policy relevant type definitions-------- */ - -/* type identifier; compares to "equal" or "not equal" */ -typedef uint16_t domaintype_t; - -/* CHINESE WALL POLICY DATA STRUCTURES - * - * current accumulated conflict type set: - * When a domain is started and has a type that is in - * a conflict set, the conflicting types are incremented in - * the aggregate set. When a domain is destroyed, the - * conflicting types to its type are decremented. - * If a domain has multiple types, this procedure works over - * all those types. - * - * conflict_aggregate_set[i] holds the number of - * running domains that have a conflict with type i. - * - * running_types[i] holds the number of running domains - * that include type i in their ssidref-referenced type set - * - * conflict_sets[i][j] is "0" if type j has no conflict - * with type i and is "1" otherwise. - */ -/* high-16 = version, low-16 = check magic */ -#define ACM_MAGIC 0x0001debc - -/* size of the SHA1 hash identifying the XML policy from which the - binary policy was created */ -#define ACM_SHA1_HASH_SIZE 20 - -/* each offset in bytes from start of the struct they - * are part of */ - -/* V3 of the policy buffer aded a version structure */ -struct acm_policy_version -{ - uint32_t major; - uint32_t minor; -}; - - -/* each buffer consists of all policy information for - * the respective policy given in the policy code - * - * acm_policy_buffer, acm_chwall_policy_buffer, - * and acm_ste_policy_buffer need to stay 32-bit aligned - * because we create binary policies also with external - * tools that assume packed representations (e.g. the java tool) - */ -struct acm_policy_buffer { - uint32_t magic; - uint32_t policy_version; /* ACM_POLICY_VERSION */ - uint32_t len; - uint32_t policy_reference_offset; - uint32_t primary_policy_code; - uint32_t primary_buffer_offset; - uint32_t secondary_policy_code; - uint32_t secondary_buffer_offset; - struct acm_policy_version xml_pol_version; /* add in V3 */ - uint8_t xml_policy_hash[ACM_SHA1_HASH_SIZE]; /* added in V4 */ -}; - - -struct acm_policy_reference_buffer { - uint32_t len; -}; - -struct acm_chwall_policy_buffer { - uint32_t policy_version; /* ACM_CHWALL_VERSION */ - uint32_t policy_code; - uint32_t chwall_max_types; - uint32_t chwall_max_ssidrefs; - uint32_t chwall_max_conflictsets; - uint32_t chwall_ssid_offset; - uint32_t chwall_conflict_sets_offset; - uint32_t chwall_running_types_offset; - uint32_t chwall_conflict_aggregate_offset; -}; - -struct acm_ste_policy_buffer { - uint32_t policy_version; /* ACM_STE_VERSION */ - uint32_t policy_code; - uint32_t ste_max_types; - uint32_t ste_max_ssidrefs; - uint32_t ste_ssid_offset; -}; - -struct acm_stats_buffer { - uint32_t magic; - uint32_t len; - uint32_t primary_policy_code; - uint32_t primary_stats_offset; - uint32_t secondary_policy_code; - uint32_t secondary_stats_offset; -}; - -struct acm_ste_stats_buffer { - uint32_t ec_eval_count; - uint32_t gt_eval_count; - uint32_t ec_denied_count; - uint32_t gt_denied_count; - uint32_t ec_cachehit_count; - uint32_t gt_cachehit_count; -}; - -struct acm_ssid_buffer { - uint32_t len; - ssidref_t ssidref; - uint32_t policy_reference_offset; - uint32_t primary_policy_code; - uint32_t primary_max_types; - uint32_t primary_types_offset; - uint32_t secondary_policy_code; - uint32_t secondary_max_types; - uint32_t secondary_types_offset; -}; - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/public/xsm/acm_ops.h b/xen/include/public/xsm/acm_ops.h deleted file mode 100644 index 1fef7a0f8b..0000000000 --- a/xen/include/public/xsm/acm_ops.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * acm_ops.h: Xen access control module hypervisor commands - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Reiner Sailer <sailer@watson.ibm.com> - * Copyright (c) 2005,2006 International Business Machines Corporation. - */ - -#ifndef __XEN_PUBLIC_ACM_OPS_H__ -#define __XEN_PUBLIC_ACM_OPS_H__ - -#include "../xen.h" -#include "acm.h" - -/* - * Make sure you increment the interface version whenever you modify this file! - * This makes sure that old versions of acm tools will stop working in a - * well-defined way (rather than crashing the machine, for instance). - */ -#define ACM_INTERFACE_VERSION 0xAAAA000A - -/************************************************************************/ - -/* - * Prototype for this hypercall is: - * int acm_op(int cmd, void *args) - * @cmd == ACMOP_??? (access control module operation). - * @args == Operation-specific extra arguments (NULL if none). - */ - - -#define ACMOP_setpolicy 1 -struct acm_setpolicy { - /* IN */ - XEN_GUEST_HANDLE_64(void) pushcache; - uint32_t pushcache_size; -}; - - -#define ACMOP_getpolicy 2 -struct acm_getpolicy { - /* IN */ - XEN_GUEST_HANDLE_64(void) pullcache; - uint32_t pullcache_size; -}; - - -#define ACMOP_dumpstats 3 -struct acm_dumpstats { - /* IN */ - XEN_GUEST_HANDLE_64(void) pullcache; - uint32_t pullcache_size; -}; - - -#define ACMOP_getssid 4 -#define ACM_GETBY_ssidref 1 -#define ACM_GETBY_domainid 2 -struct acm_getssid { - /* IN */ - uint32_t get_ssid_by; /* ACM_GETBY_* */ - union { - domaintype_t domainid; - ssidref_t ssidref; - } id; - XEN_GUEST_HANDLE_64(void) ssidbuf; - uint32_t ssidbuf_size; -}; - -#define ACMOP_getdecision 5 -struct acm_getdecision { - /* IN */ - uint32_t get_decision_by1; /* ACM_GETBY_* */ - uint32_t get_decision_by2; /* ACM_GETBY_* */ - union { - domaintype_t domainid; - ssidref_t ssidref; - } id1; - union { - domaintype_t domainid; - ssidref_t ssidref; - } id2; - uint32_t hook; - /* OUT */ - uint32_t acm_decision; -}; - - -#define ACMOP_chgpolicy 6 -struct acm_change_policy { - /* IN */ - XEN_GUEST_HANDLE_64(void) policy_pushcache; - uint32_t policy_pushcache_size; - XEN_GUEST_HANDLE_64(void) del_array; - uint32_t delarray_size; - XEN_GUEST_HANDLE_64(void) chg_array; - uint32_t chgarray_size; - /* OUT */ - /* array with error code */ - XEN_GUEST_HANDLE_64(void) err_array; - uint32_t errarray_size; -}; - -#define ACMOP_relabeldoms 7 -struct acm_relabel_doms { - /* IN */ - XEN_GUEST_HANDLE_64(void) relabel_map; - uint32_t relabel_map_size; - /* OUT */ - XEN_GUEST_HANDLE_64(void) err_array; - uint32_t errarray_size; -}; - -/* future interface to Xen */ -struct xen_acmctl { - uint32_t cmd; - uint32_t interface_version; - union { - struct acm_setpolicy setpolicy; - struct acm_getpolicy getpolicy; - struct acm_dumpstats dumpstats; - struct acm_getssid getssid; - struct acm_getdecision getdecision; - struct acm_change_policy change_policy; - struct acm_relabel_doms relabel_doms; - } u; -}; - -typedef struct xen_acmctl xen_acmctl_t; -DEFINE_XEN_GUEST_HANDLE(xen_acmctl_t); - -#endif /* __XEN_PUBLIC_ACM_OPS_H__ */ - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 652a39c5b0..c86759596f 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -11,7 +11,6 @@ #include <public/domctl.h> #include <public/sysctl.h> #include <public/vcpu.h> -#include <public/xsm/acm.h> #include <xen/time.h> #include <xen/timer.h> #include <xen/grant_table.h> @@ -401,7 +400,7 @@ static inline void get_knownalive_domain(struct domain *d) void domain_update_node_affinity(struct domain *d); struct domain *domain_create( - domid_t domid, unsigned int domcr_flags, ssidref_t ssidref); + domid_t domid, unsigned int domcr_flags, uint32_t ssidref); /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */ #define _DOMCRF_hvm 0 #define DOMCRF_hvm (1U<<_DOMCRF_hvm) diff --git a/xen/include/xsm/acm/acm_core.h b/xen/include/xsm/acm/acm_core.h deleted file mode 100644 index 718f9b7f89..0000000000 --- a/xen/include/xsm/acm/acm_core.h +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************** - * acm_core.h - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype header file describing core data types and constants - * for the access control module and relevant policies - * - */ - -#ifndef _ACM_CORE_H -#define _ACM_CORE_H - -#include <xen/spinlock.h> -#include <xen/list.h> -#include <public/xsm/acm.h> -#include <public/xsm/acm_ops.h> -#include <xsm/acm/acm_endian.h> - -#define ACM_DEFAULT_SECURITY_POLICY \ - ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY - -/* Xen-internal representation of the binary policy */ -struct acm_binary_policy { - char *policy_reference_name; - u16 primary_policy_code; - u16 secondary_policy_code; - struct acm_policy_version xml_pol_version; - u8 xml_policy_hash[ACM_SHA1_HASH_SIZE]; -}; - -struct chwall_binary_policy { - u32 max_types; - u32 max_ssidrefs; - u32 max_conflictsets; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - domaintype_t *conflict_aggregate_set; /* [max_types] */ - domaintype_t *running_types; /* [max_types] */ - domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/ -}; - -struct ste_binary_policy { - u32 max_types; - u32 max_ssidrefs; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - atomic_t ec_eval_count, gt_eval_count; - atomic_t ec_denied_count, gt_denied_count; - atomic_t ec_cachehit_count, gt_cachehit_count; -}; - -/* 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; -/* use the lock when reading / changing binary policy ! */ -extern rwlock_t acm_bin_pol_rwlock; -extern rwlock_t ssid_list_rwlock; - -/* subject and object type definitions */ -#define ACM_DATATYPE_domain 1 - -/* defines number of access decisions to other domains can be cached - * one entry per domain, TE does not distinguish evtchn or grant_table */ -#define ACM_TE_CACHE_SIZE 8 -#define ACM_STE_valid 0 -#define ACM_STE_free 1 - -/* cache line: - * if cache_line.valid==ACM_STE_valid, then - * STE decision is cached as "permitted" - * on domain cache_line.id - */ -struct acm_ste_cache_line { - int valid; /* ACM_STE_* */ - domid_t id; -}; - -/* general definition of a subject security id */ -struct acm_ssid_domain { - struct list_head node; /* all are chained together */ - int datatype; /* type of subject (e.g., partition): ACM_DATATYPE_* */ - ssidref_t ssidref; /* combined security reference */ - ssidref_t old_ssidref; /* holds previous value of ssidref during relabeling */ - void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */ - void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */ - struct domain *subject;/* backpointer to subject structure */ - domid_t domainid; /* replicate id */ -}; - -/* chinese wall ssid type */ -struct chwall_ssid { - ssidref_t chwall_ssidref; -}; - -/* simple type enforcement ssid type */ -struct ste_ssid { - ssidref_t ste_ssidref; - struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */ -}; - -/* macros to access ssidref for primary / secondary policy - * primary ssidref = lower 16 bit - * secondary ssidref = higher 16 bit - */ -#define ACM_PRIMARY(ssidref) \ - ((ssidref) & 0xffff) - -#define ACM_SECONDARY(ssidref) \ - ((ssidref) >> 16) - -#define GET_SSIDREF(POLICY, ssidref) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) - -/* macros to access ssid pointer for primary / secondary policy */ -#define GET_SSIDP(POLICY, ssid) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ((ssid)->primary_ssid) : ((ssid)->secondary_ssid) - -#define ACM_INVALID_SSIDREF (0xffffffff) - -struct acm_sized_buffer -{ - uint32_t *array; - uint num_items; - uint position; -}; - -static inline int acm_array_append_tuple(struct acm_sized_buffer *buf, - uint32_t a, uint32_t b) -{ - uint i; - if (buf == NULL) - return 0; - - i = buf->position; - - if ((i + 2) > buf->num_items) - return 0; - - buf->array[i] = cpu_to_be32(a); - buf->array[i+1] = cpu_to_be32(b); - buf->position += 2; - return 1; -} - -/* protos */ -int acm_init_domain_ssid(struct domain *, ssidref_t ssidref); -void acm_free_domain_ssid(struct domain *); -int acm_init_binary_policy(u32 policy_code); -int acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size); -int do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy, - struct acm_sized_buffer *, struct acm_sized_buffer *, - struct acm_sized_buffer *); -int acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size); -int acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size); -int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size); -int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook); -int acm_set_policy_reference(u8 * buf, u32 buf_size); -int acm_dump_policy_reference(u8 *buf, u32 buf_size); -int acm_change_policy(struct acm_change_policy *); -int acm_relabel_domains(struct acm_relabel_doms *); -int do_chwall_init_state_curr(struct acm_sized_buffer *); -int do_ste_init_state_curr(struct acm_sized_buffer *); - -/* variables */ -extern ssidref_t dom0_chwall_ssidref; -extern ssidref_t dom0_ste_ssidref; -#define ACM_MAX_NUM_TYPES (256) - -/* traversing the list of ssids */ -extern struct list_head ssid_list; -#define for_each_acmssid( N ) \ - for ( N = (struct acm_ssid_domain *)ssid_list.next; \ - N != (struct acm_ssid_domain *)&ssid_list; \ - N = (struct acm_ssid_domain *)N->node.next ) - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/xsm/acm/acm_endian.h b/xen/include/xsm/acm/acm_endian.h deleted file mode 100644 index 11781dd4f4..0000000000 --- a/xen/include/xsm/acm/acm_endian.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************** - * acm_endian.h - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Stefan Berger <stefanb@watson.ibm.com> - * - * Contributions: - * Reiner Sailer <sailer@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype header file defining endian-dependent functions for the - * big-endian policy interface - * - */ - -#ifndef _ACM_ENDIAN_H -#define _ACM_ENDIAN_H - -#include <asm/byteorder.h> - -static inline void arrcpy16(u16 *dest, const u16 *src, size_t n) -{ - unsigned int i; - for ( i = 0; i < n; i++ ) - dest[i] = cpu_to_be16(src[i]); -} - -static inline void arrcpy32(u32 *dest, const u32 *src, size_t n) -{ - unsigned int i; - for ( i = 0; i < n; i++ ) - dest[i] = cpu_to_be32(src[i]); -} - -static inline void arrcpy( - void *dest, const void *src, unsigned int elsize, size_t n) -{ - switch ( elsize ) - { - case sizeof(u16): - arrcpy16((u16 *)dest, (u16 *)src, n); - break; - - case sizeof(u32): - arrcpy32((u32 *)dest, (u32 *)src, n); - break; - - default: - memcpy(dest, src, elsize*n); - } -} - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/xsm/acm/acm_hooks.h b/xen/include/xsm/acm/acm_hooks.h deleted file mode 100644 index 67bd49f570..0000000000 --- a/xen/include/xsm/acm/acm_hooks.h +++ /dev/null @@ -1,374 +0,0 @@ -/**************************************************************** - * acm_hooks.h - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * acm header file implementing the global (policy-independent) - * sHype hooks that are called throughout Xen. - * - */ - -#ifndef _ACM_HOOKS_H -#define _ACM_HOOKS_H - -#include <xen/config.h> -#include <xen/errno.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/delay.h> -#include <xen/sched.h> -#include <xen/multiboot.h> -#include <public/xsm/acm.h> -#include <xsm/acm/acm_core.h> -#include <public/domctl.h> -#include <public/event_channel.h> -#include <asm/current.h> - -/* - * HOOK structure and meaning (justifies a few words about our model): - * - * General idea: every policy-controlled system operation is reflected in a - * transaction in the system's security state - * - * Keeping the security state consistent requires "atomic" transactions. - * The name of the hooks to place around policy-controlled transactions - * reflects this. If authorizations do not involve security state changes, - * then and only then POST and FAIL hooks remain empty since we don't care - * about the eventual outcome of the operation from a security viewpoint. - * - * PURPOSE of hook types: - * ====================== - * PRE-Hooks - * a) general authorization to guard a controlled system operation - * b) prepare security state change - * (means: fail hook must be able to "undo" this) - * - * POST-Hooks - * a) commit prepared state change - * - * FAIL-Hooks - * a) roll-back prepared security state change from PRE-Hook - * - * - * PLACEMENT of hook types: - * ======================== - * PRE-Hooks must be called before a guarded/controlled system operation - * is started. They return ACM_ACCESS_PERMITTED, ACM_ACCESS_DENIED or - * error. Operation must be aborted if return is not ACM_ACCESS_PERMITTED. - * - * POST-Hooks must be called after a successful system operation. - * There is no return value: commit never fails. - * - * FAIL-Hooks must be called: - * a) if system transaction (operation) fails after calling the PRE-hook - * b) if another (secondary) policy denies access in its PRE-Hook - * (policy layering is useful but requires additional handling) - * - * Hook model from a security transaction viewpoint: - * start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success - * (pre-hook) \ (post-hook) - * \ - * fail - * \ - * \ - * roll-back - * (fail-hook) - * \ - * sys-ops error - * - */ - -struct acm_operations { - /* policy management functions (must always be defined!) */ - int (*init_domain_ssid) (void **ssid, ssidref_t ssidref); - void (*free_domain_ssid) (void *ssid); - int (*dump_binary_policy) (u8 *buffer, u32 buf_size); - int (*test_binary_policy) (u8 *buffer, u32 buf_size, - int is_bootpolicy, - struct acm_sized_buffer *); - int (*set_binary_policy) (u8 *buffer, u32 buf_size); - int (*dump_statistics) (u8 *buffer, u16 buf_size); - int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size); - /* domain management control hooks (can be NULL) */ - int (*domain_create) (void *subject_ssid, ssidref_t ssidref, - domid_t domid); - void (*domain_destroy) (void *object_ssid, struct domain *d); - /* event channel control hooks (can be NULL) */ - int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2); - void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2); - int (*pre_eventchannel_interdomain) (domid_t id); - void (*fail_eventchannel_interdomain) (domid_t id); - /* grant table control hooks (can be NULL) */ - int (*pre_grant_map_ref) (domid_t id); - void (*fail_grant_map_ref) (domid_t id); - int (*pre_grant_setup) (domid_t id); - void (*fail_grant_setup) (domid_t id); - /* generic domain-requested decision hooks (can be NULL) */ - int (*sharing) (ssidref_t ssidref1, - ssidref_t ssidref2); - int (*authorization) (ssidref_t ssidref1, - ssidref_t ssidref2); - int (*conflictset) (ssidref_t ssidref1); - /* determine whether the default policy is installed */ - int (*is_default_policy) (void); -}; - -/* global variables */ -extern struct acm_operations *acm_primary_ops; -extern struct acm_operations *acm_secondary_ops; - -/* if ACM_TRACE_MODE defined, all hooks should - * print a short trace message */ -/* #define ACM_TRACE_MODE */ - -#ifdef ACM_TRACE_MODE -# define traceprintk(fmt, args...) printk(fmt, ## args) -#else -# define traceprintk(fmt, args...) -#endif - -/* if ACM_DEBUG defined, all hooks should - * print a short trace message (comment it out - * when not in testing mode ) - */ -/* #define ACM_DEBUG */ - -#ifdef ACM_DEBUG -# define printkd(fmt, args...) printk(fmt, ## args) -#else -# define printkd(fmt, args...) -#endif - -#ifndef ACM_SECURITY - -static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2) -{ return 0; } -static inline int acm_pre_eventchannel_interdomain(domid_t id) -{ return 0; } -static inline int acm_pre_grant_map_ref(domid_t id) -{ return 0; } -static inline int acm_pre_grant_setup(domid_t id) -{ return 0; } -static inline int acm_is_policy(char *buf, unsigned long len) -{ return 0; } -static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) -{ return 0; } -static inline int acm_authorization(ssidref_t ssidref1, ssidref_t ssidref2) -{ return 0; } -static inline int acm_conflictset(ssidref_t ssidref1) -{ return 0; } -static inline int acm_domain_create(struct domain *d, ssidref_t ssidref) -{ return 0; } -static inline void acm_domain_destroy(struct domain *d) -{ return; } - -#define DOM0_SSIDREF 0x0 - -#else - -static inline void acm_domain_ssid_onto_list(struct acm_ssid_domain *ssid) -{ - write_lock(&ssid_list_rwlock); - list_add(&ssid->node, &ssid_list); - write_unlock(&ssid_list_rwlock); -} - -static inline void acm_domain_ssid_off_list(struct acm_ssid_domain *ssid) -{ - write_lock(&ssid_list_rwlock); - list_del(&ssid->node); - write_unlock(&ssid_list_rwlock); -} - -static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2) -{ - if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && - acm_primary_ops->pre_eventchannel_unbound(id1, id2)) - return ACM_ACCESS_DENIED; - else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && - acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) { - /* roll-back primary */ - if (acm_primary_ops->fail_eventchannel_unbound != NULL) - acm_primary_ops->fail_eventchannel_unbound(id1, id2); - return ACM_ACCESS_DENIED; - } else - return ACM_ACCESS_PERMITTED; -} - -static inline int acm_pre_eventchannel_interdomain(domid_t id) -{ - if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) && - acm_primary_ops->pre_eventchannel_interdomain(id)) - return ACM_ACCESS_DENIED; - else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) && - acm_secondary_ops->pre_eventchannel_interdomain(id)) { - /* roll-back primary */ - if (acm_primary_ops->fail_eventchannel_interdomain != NULL) - acm_primary_ops->fail_eventchannel_interdomain(id); - return ACM_ACCESS_DENIED; - } else - return ACM_ACCESS_PERMITTED; -} - - -static inline int acm_pre_grant_map_ref(domid_t id) -{ - if ( (acm_primary_ops->pre_grant_map_ref != NULL) && - acm_primary_ops->pre_grant_map_ref(id) ) - { - return ACM_ACCESS_DENIED; - } - else if ( (acm_secondary_ops->pre_grant_map_ref != NULL) && - acm_secondary_ops->pre_grant_map_ref(id) ) - { - /* roll-back primary */ - if ( acm_primary_ops->fail_grant_map_ref != NULL ) - acm_primary_ops->fail_grant_map_ref(id); - return ACM_ACCESS_DENIED; - } - else - { - return ACM_ACCESS_PERMITTED; - } -} - -static inline int acm_pre_grant_setup(domid_t id) -{ - if ( (acm_primary_ops->pre_grant_setup != NULL) && - acm_primary_ops->pre_grant_setup(id) ) - { - return ACM_ACCESS_DENIED; - } - else if ( (acm_secondary_ops->pre_grant_setup != NULL) && - acm_secondary_ops->pre_grant_setup(id) ) - { - /* roll-back primary */ - if (acm_primary_ops->fail_grant_setup != NULL) - acm_primary_ops->fail_grant_setup(id); - return ACM_ACCESS_DENIED; - } - else - { - return ACM_ACCESS_PERMITTED; - } -} - - -static inline void acm_domain_destroy(struct domain *d) -{ - void *ssid = d->ssid; - if (ssid != NULL) { - if (acm_primary_ops->domain_destroy != NULL) - acm_primary_ops->domain_destroy(ssid, d); - if (acm_secondary_ops->domain_destroy != NULL) - acm_secondary_ops->domain_destroy(ssid, d); - /* free security ssid for the destroyed domain (also if null policy */ - acm_domain_ssid_off_list(ssid); - acm_free_domain_ssid(d); - } -} - - -static inline int acm_domain_create(struct domain *d, ssidref_t ssidref) -{ - void *subject_ssid = current->domain->ssid; - domid_t domid = d->domain_id; - int rc; - - read_lock(&acm_bin_pol_rwlock); - /* - To be called when a domain is created; returns '0' if the - domain is allowed to be created, != '0' if not. - */ - rc = acm_init_domain_ssid(d, ssidref); - if (rc != ACM_OK) - goto error_out; - - if ((acm_primary_ops->domain_create != NULL) && - acm_primary_ops->domain_create(subject_ssid, ssidref, domid)) { - rc = ACM_ACCESS_DENIED; - } else if ((acm_secondary_ops->domain_create != NULL) && - acm_secondary_ops->domain_create(subject_ssid, ssidref, - domid)) { - /* roll-back primary */ - if (acm_primary_ops->domain_destroy != NULL) - acm_primary_ops->domain_destroy(d->ssid, d); - rc = ACM_ACCESS_DENIED; - } - - if ( rc == ACM_OK ) - { - acm_domain_ssid_onto_list(d->ssid); - } else { - acm_free_domain_ssid(d); - } - -error_out: - read_unlock(&acm_bin_pol_rwlock); - return rc; -} - - -static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) -{ - if ((acm_primary_ops->sharing != NULL) && - acm_primary_ops->sharing(ssidref1, ssidref2)) - return ACM_ACCESS_DENIED; - else if ((acm_secondary_ops->sharing != NULL) && - acm_secondary_ops->sharing(ssidref1, ssidref2)) { - return ACM_ACCESS_DENIED; - } else - return ACM_ACCESS_PERMITTED; -} - - -static inline int acm_authorization(ssidref_t ssidref1, ssidref_t ssidref2) -{ - if ((acm_primary_ops->authorization != NULL) && - acm_primary_ops->authorization(ssidref1, ssidref2)) - return ACM_ACCESS_DENIED; - else if ((acm_secondary_ops->authorization != NULL) && - acm_secondary_ops->authorization(ssidref1, ssidref2)) { - return ACM_ACCESS_DENIED; - } else - return acm_sharing(ssidref1, ssidref2); -} - - -static inline int acm_conflictset(ssidref_t ssidref1) -{ - if ((acm_primary_ops->conflictset != NULL) && - acm_primary_ops->conflictset(ssidref1)) - return ACM_ACCESS_DENIED; - else if ((acm_secondary_ops->conflictset != NULL) && - acm_secondary_ops->conflictset(ssidref1)) - return ACM_ACCESS_DENIED; - return ACM_ACCESS_PERMITTED; -} - -/* Return true iff buffer has an acm policy magic number. */ -extern int acm_is_policy(char *buf, unsigned long len); - -#define DOM0_SSIDREF (dom0_ste_ssidref << 16 | dom0_chwall_ssidref) - -#endif - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/Makefile b/xen/xsm/Makefile index 02f55d8e1a..16c13b507f 100644 --- a/xen/xsm/Makefile +++ b/xen/xsm/Makefile @@ -5,4 +5,3 @@ obj-y += dummy.o endif subdir-$(FLASK_ENABLE) += flask -subdir-$(ACM_SECURITY) += acm diff --git a/xen/xsm/acm/Makefile b/xen/xsm/acm/Makefile deleted file mode 100644 index b3ddbc13c8..0000000000 --- a/xen/xsm/acm/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-y += acm_core.o -obj-y += acm_policy.o -obj-y += acm_simple_type_enforcement_hooks.o -obj-y += acm_chinesewall_hooks.o -obj-y += acm_null_hooks.o -obj-y += acm_xsm_hooks.o -obj-y += acm_ops.o diff --git a/xen/xsm/acm/acm_chinesewall_hooks.c b/xen/xsm/acm/acm_chinesewall_hooks.c deleted file mode 100644 index 977c45ff2a..0000000000 --- a/xen/xsm/acm/acm_chinesewall_hooks.c +++ /dev/null @@ -1,721 +0,0 @@ -/**************************************************************** - * acm_chinesewall_hooks.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * Contributions: - * Stefan Berger <stefanb@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype Chinese Wall Policy for Xen - * This code implements the hooks that are called - * throughout Xen operations and decides authorization - * based on domain types and Chinese Wall conflict type - * sets. The CHWALL policy decides if a new domain can be started - * based on the types of running domains and the type of the - * new domain to be started. If the new domain's type is in - * conflict with types of running domains, then this new domain - * is not allowed to be created. A domain can have multiple types, - * in which case all types of a new domain must be conflict-free - * with all types of already running domains. - * - * indent -i4 -kr -nut - * - */ - -#include <xen/config.h> -#include <xen/errno.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/delay.h> -#include <xen/sched.h> -#include <public/xsm/acm.h> -#include <asm/atomic.h> -#include <xsm/acm/acm_core.h> -#include <xsm/acm/acm_hooks.h> -#include <xsm/acm/acm_endian.h> - -ssidref_t dom0_chwall_ssidref = 0x0001; - -/* local cache structures for chinese wall policy */ -struct chwall_binary_policy chwall_bin_pol; - -/* - * Initializing chinese wall policy (will be filled by policy partition - * using setpolicy command) - */ -int acm_init_chwall_policy(void) -{ - /* minimal startup policy; policy write-locked already */ - chwall_bin_pol.max_types = 1; - chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref; - chwall_bin_pol.max_conflictsets = 1; - chwall_bin_pol.ssidrefs = - (domaintype_t *) xmalloc_array(domaintype_t, - chwall_bin_pol.max_ssidrefs * - chwall_bin_pol.max_types); - chwall_bin_pol.conflict_sets = - (domaintype_t *) xmalloc_array(domaintype_t, - chwall_bin_pol.max_conflictsets * - chwall_bin_pol.max_types); - chwall_bin_pol.running_types = - (domaintype_t *) xmalloc_array(domaintype_t, - chwall_bin_pol.max_types); - chwall_bin_pol.conflict_aggregate_set = - (domaintype_t *) xmalloc_array(domaintype_t, - chwall_bin_pol.max_types); - - if ( (chwall_bin_pol.conflict_sets == NULL) - || (chwall_bin_pol.running_types == NULL) - || (chwall_bin_pol.ssidrefs == NULL) - || (chwall_bin_pol.conflict_aggregate_set == NULL) ) - return ACM_INIT_SSID_ERROR; - - /* initialize state */ - memset((void *) chwall_bin_pol.ssidrefs, 0, - chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types * - sizeof(domaintype_t)); - memset((void *) chwall_bin_pol.conflict_sets, 0, - chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types * - sizeof(domaintype_t)); - memset((void *) chwall_bin_pol.running_types, 0, - chwall_bin_pol.max_types * sizeof(domaintype_t)); - memset((void *) chwall_bin_pol.conflict_aggregate_set, 0, - chwall_bin_pol.max_types * sizeof(domaintype_t)); - return ACM_OK; -} - - -static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) -{ - struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); - traceprintk("%s.\n", __func__); - - if ( chwall_ssidp == NULL ) - return ACM_INIT_SSID_ERROR; - - chwall_ssidp->chwall_ssidref = - GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - - if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs ) - { - printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset " - "(0).\n", - __func__, chwall_ssidp->chwall_ssidref); - xfree(chwall_ssidp); - return ACM_INIT_SSID_ERROR; - } - (*chwall_ssid) = chwall_ssidp; - printkd("%s: determined chwall_ssidref to %x.\n", - __func__, chwall_ssidp->chwall_ssidref); - return ACM_OK; -} - - -static void chwall_free_domain_ssid(void *chwall_ssid) -{ - xfree(chwall_ssid); - return; -} - - -/* dump chinese wall cache; policy read-locked already */ -static int chwall_dump_policy(u8 * buf, u32 buf_size) -{ - struct acm_chwall_policy_buffer *chwall_buf = - (struct acm_chwall_policy_buffer *) buf; - int ret = 0; - - if ( buf_size < sizeof(struct acm_chwall_policy_buffer) ) - return -EINVAL; - - chwall_buf->chwall_max_types = cpu_to_be32(chwall_bin_pol.max_types); - chwall_buf->chwall_max_ssidrefs = cpu_to_be32(chwall_bin_pol.max_ssidrefs); - chwall_buf->policy_code = cpu_to_be32(ACM_CHINESE_WALL_POLICY); - chwall_buf->chwall_ssid_offset = - cpu_to_be32(sizeof(struct acm_chwall_policy_buffer)); - chwall_buf->chwall_max_conflictsets = - cpu_to_be32(chwall_bin_pol.max_conflictsets); - chwall_buf->chwall_conflict_sets_offset = - cpu_to_be32(be32_to_cpu(chwall_buf->chwall_ssid_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * - chwall_bin_pol.max_types); - chwall_buf->chwall_running_types_offset = - cpu_to_be32(be32_to_cpu(chwall_buf->chwall_conflict_sets_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets * - chwall_bin_pol.max_types); - chwall_buf->chwall_conflict_aggregate_offset = - cpu_to_be32(be32_to_cpu(chwall_buf->chwall_running_types_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types); - - ret = be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types; - - ret = (ret + 7) & ~7; - - if ( buf_size < ret ) - return -EINVAL; - - /* now copy buffers over */ - arrcpy16((u16 *) (buf + be32_to_cpu(chwall_buf->chwall_ssid_offset)), - chwall_bin_pol.ssidrefs, - chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types); - - arrcpy16((u16 *) (buf + - be32_to_cpu(chwall_buf->chwall_conflict_sets_offset)), - chwall_bin_pol.conflict_sets, - chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types); - - arrcpy16((u16 *) (buf + - be32_to_cpu(chwall_buf->chwall_running_types_offset)), - chwall_bin_pol.running_types, chwall_bin_pol.max_types); - - arrcpy16((u16 *) (buf + - be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset)), - chwall_bin_pol.conflict_aggregate_set, - chwall_bin_pol.max_types); - return ret; -} - -/* - * Adapt security state (running_types and conflict_aggregate_set) to all - * running domains; chwall_init_state is called when a policy is changed - * to bring the security information into a consistent state and to detect - * violations (return != 0) from a security point of view, we simulate - * that all running domains are re-started - */ -static int -chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, - domaintype_t * ssidrefs, - domaintype_t * conflict_sets, - domaintype_t * running_types, - domaintype_t * conflict_aggregate_set, - struct acm_sized_buffer *errors /* may be NULL */) -{ - int violation = 0, i, j; - struct chwall_ssid *chwall_ssid; - ssidref_t chwall_ssidref; - struct acm_ssid_domain *rawssid; - - read_lock(&ssid_list_rwlock); - - /* go through all domains and adjust policy as if this domain was - * started now - */ - for_each_acmssid( rawssid ) - { - chwall_ssid = - GET_SSIDP(ACM_CHINESE_WALL_POLICY, rawssid); - chwall_ssidref = chwall_ssid->chwall_ssidref; - traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", - __func__, d->domain_id, chwall_ssidref); - /* a) adjust types ref-count for running domains */ - for ( i = 0; i < chwall_buf->chwall_max_types; i++ ) - running_types[i] += - ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]; - - /* b) check for conflict */ - for ( i = 0; i < chwall_buf->chwall_max_types; i++ ) - if ( conflict_aggregate_set[i] && - ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i] ) - { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", - __func__, i); - violation = 1; - - acm_array_append_tuple(errors, ACM_CHWALL_CONFLICT, i); - - goto out; - } - - /* set violation and break out of the loop */ - /* c) adapt conflict aggregate set for this domain - * (notice conflicts) - */ - for ( i = 0; i < chwall_buf->chwall_max_conflictsets; i++ ) - { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for ( j = 0; j < chwall_buf->chwall_max_types; j++ ) - if ( conflict_sets[i * chwall_buf->chwall_max_types + j] && - ssidrefs[chwall_ssidref * - chwall_buf->chwall_max_types + j] ) - { - common = 1; - break; - } - - if ( common == 0 ) - continue; /* try next conflict set */ - - /* now add types of the conflict set to conflict_aggregate_set - * (except types in chwall_ssidref) - */ - for ( j = 0; j < chwall_buf->chwall_max_types; j++ ) - if ( conflict_sets[i * chwall_buf->chwall_max_types + j] && - !ssidrefs[chwall_ssidref * - chwall_buf->chwall_max_types + j] ) - conflict_aggregate_set[j]++; - } - } - out: - read_unlock(&ssid_list_rwlock); - return violation; - /* returning "violation != 0" means that the currently running set of - * domains would not be possible if the new policy had been enforced - * before starting them; for chinese wall, this means that the new - * policy includes at least one conflict set of which more than one - * type is currently running - */ -} - - -int -do_chwall_init_state_curr(struct acm_sized_buffer *errors) -{ - struct acm_chwall_policy_buffer chwall_buf = - { - /* only these two are important */ - .chwall_max_types = chwall_bin_pol.max_types, - .chwall_max_conflictsets = chwall_bin_pol.max_conflictsets, - }; - /* reset running_types and aggregate set for recalculation */ - memset(chwall_bin_pol.running_types, - 0x0, - sizeof(domaintype_t) * chwall_bin_pol.max_types); - memset(chwall_bin_pol.conflict_aggregate_set, - 0x0, - sizeof(domaintype_t) * chwall_bin_pol.max_types); - return chwall_init_state(&chwall_buf, - chwall_bin_pol.ssidrefs, - chwall_bin_pol.conflict_sets, - chwall_bin_pol.running_types, - chwall_bin_pol.conflict_aggregate_set, - errors); -} - -/* - * Attempt to set the policy. This function must be called in test_only - * mode first to only perform checks. A second call then does the - * actual changes. - */ -static int _chwall_update_policy(u8 *buf, u32 buf_size, int test_only, - struct acm_sized_buffer *errors) -{ - int rc = -EFAULT; - /* policy write-locked already */ - struct acm_chwall_policy_buffer *chwall_buf = - (struct acm_chwall_policy_buffer *) buf; - void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, - *conflict_aggregate_set = NULL; - - /* 1. allocate new buffers */ - ssids = - xmalloc_array(domaintype_t, - chwall_buf->chwall_max_types * - chwall_buf->chwall_max_ssidrefs); - conflict_sets = - xmalloc_array(domaintype_t, - chwall_buf->chwall_max_conflictsets * - chwall_buf->chwall_max_types); - running_types = - xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); - conflict_aggregate_set = - xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); - - if ( (ssids == NULL) || (conflict_sets == NULL) || - (running_types == NULL) || (conflict_aggregate_set == NULL) ) - goto error_free; - - /* 2. set new policy */ - if ( chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > - buf_size ) - goto error_free; - - arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs); - - if ( chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * - chwall_buf->chwall_max_conflictsets > buf_size ) - goto error_free; - - arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * - chwall_buf->chwall_max_conflictsets); - - /* we also use new state buffers since max_types can change */ - memset(running_types, 0, - sizeof(domaintype_t) * chwall_buf->chwall_max_types); - memset(conflict_aggregate_set, 0, - sizeof(domaintype_t) * chwall_buf->chwall_max_types); - - /* 3. now re-calculate the state for the new policy based on - * running domains; this can fail if new policy is conflicting - * with running domains - */ - if ( chwall_init_state(chwall_buf, ssids, - conflict_sets, running_types, - conflict_aggregate_set, - errors)) - { - printk("%s: New policy conflicts with running domains. Policy load aborted.\n", - __func__); - goto error_free; /* new policy conflicts with running domains */ - } - - /* if this was only a test run, exit with ACM_OK */ - if ( test_only ) - { - rc = ACM_OK; - goto error_free; - } - - /* 4. free old policy buffers, replace with new ones */ - chwall_bin_pol.max_types = chwall_buf->chwall_max_types; - chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs; - chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets; - xfree(chwall_bin_pol.ssidrefs); - xfree(chwall_bin_pol.conflict_aggregate_set); - xfree(chwall_bin_pol.running_types); - xfree(chwall_bin_pol.conflict_sets); - chwall_bin_pol.ssidrefs = ssids; - chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set; - chwall_bin_pol.running_types = running_types; - chwall_bin_pol.conflict_sets = conflict_sets; - - return ACM_OK; - - error_free: - if ( !test_only ) - printk("%s: ERROR setting policy.\n", __func__); - - xfree(ssids); - xfree(conflict_sets); - xfree(running_types); - xfree(conflict_aggregate_set); - return rc; -} - -/* - * This function MUST be called before the chwall_ste_policy function! - */ -static int chwall_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy, - struct acm_sized_buffer *errors) -{ - struct acm_chwall_policy_buffer *chwall_buf = - (struct acm_chwall_policy_buffer *) buf; - - if ( buf_size < sizeof(struct acm_chwall_policy_buffer) ) - return -EINVAL; - - /* rewrite the policy due to endianess */ - chwall_buf->policy_code = be32_to_cpu(chwall_buf->policy_code); - chwall_buf->policy_version = be32_to_cpu(chwall_buf->policy_version); - chwall_buf->chwall_max_types = - be32_to_cpu(chwall_buf->chwall_max_types); - chwall_buf->chwall_max_ssidrefs = - be32_to_cpu(chwall_buf->chwall_max_ssidrefs); - chwall_buf->chwall_max_conflictsets = - be32_to_cpu(chwall_buf->chwall_max_conflictsets); - chwall_buf->chwall_ssid_offset = - be32_to_cpu(chwall_buf->chwall_ssid_offset); - chwall_buf->chwall_conflict_sets_offset = - be32_to_cpu(chwall_buf->chwall_conflict_sets_offset); - chwall_buf->chwall_running_types_offset = - be32_to_cpu(chwall_buf->chwall_running_types_offset); - chwall_buf->chwall_conflict_aggregate_offset = - be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset); - - /* policy type and version checks */ - if ( (chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) || - (chwall_buf->policy_version != ACM_CHWALL_VERSION) ) - return -EINVAL; - - /* during boot dom0_chwall_ssidref is set */ - if ( is_bootpolicy && - (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs) ) - return -EINVAL; - - return _chwall_update_policy(buf, buf_size, 1, errors); -} - -static int chwall_set_policy(u8 *buf, u32 buf_size) -{ - return _chwall_update_policy(buf, buf_size, 0, NULL); -} - -static int chwall_dump_stats(u8 * buf, u16 len) -{ - /* no stats for Chinese Wall Policy */ - return 0; -} - -static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len) -{ - int i; - - /* fill in buffer */ - if ( chwall_bin_pol.max_types > len ) - return -EFAULT; - - if ( ssidref >= chwall_bin_pol.max_ssidrefs ) - return -EFAULT; - - /* read types for chwall ssidref */ - for ( i = 0; i < chwall_bin_pol.max_types; i++ ) - { - if ( chwall_bin_pol. - ssidrefs[ssidref * chwall_bin_pol.max_types + i] ) - buf[i] = 1; - else - buf[i] = 0; - } - return chwall_bin_pol.max_types; -} - -/*************************** - * Authorization functions - ***************************/ - -/* -------- DOMAIN OPERATION HOOKS -----------*/ - -static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref) -{ - ssidref_t chwall_ssidref; - int i, j; - - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - - if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs ) - { - printk("%s: ERROR chwall_ssidref > max(%x).\n", - __func__, chwall_bin_pol.max_ssidrefs - 1); - return ACM_ACCESS_DENIED; - } - - /* A: chinese wall check for conflicts */ - for ( i = 0; i < chwall_bin_pol.max_types; i++ ) - if ( chwall_bin_pol.conflict_aggregate_set[i] && - chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + i] ) - { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); - return ACM_ACCESS_DENIED; - } - - /* B: chinese wall conflict set adjustment (so that other - * other domains simultaneously created are evaluated against - * this new set) - */ - for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ ) - { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for ( j = 0; j < chwall_bin_pol.max_types; j++ ) - if ( chwall_bin_pol. - conflict_sets[i * chwall_bin_pol.max_types + j] - && chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + j] ) - { - common = 1; - break; - } - if ( common == 0 ) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for ( j = 0; j < chwall_bin_pol.max_types; j++ ) - if ( chwall_bin_pol. - conflict_sets[i * chwall_bin_pol.max_types + j] - && !chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]++; - } - return ACM_ACCESS_PERMITTED; -} - - -static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref) -{ - int i; - ssidref_t chwall_ssidref; - - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - /* adjust types ref-count for running domains */ - for ( i = 0; i < chwall_bin_pol.max_types; i++ ) - chwall_bin_pol.running_types[i] += - chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + i]; -} - - -/* - * To be called when creating a domain. If this call is unsuccessful, - * no state changes have occurred (adjustments of counters etc.). If it - * was successful, state was changed and can be undone using - * chwall_domain_destroy. - */ -static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref, - domid_t domid) -{ - int rc; - read_lock(&acm_bin_pol_rwlock); - - rc = _chwall_pre_domain_create(subject_ssid, ssidref); - if ( rc == ACM_ACCESS_PERMITTED ) - _chwall_post_domain_create(domid, ssidref); - - read_unlock(&acm_bin_pol_rwlock); - return rc; -} - -/* - * This function undoes everything a successful call to - * chwall_domain_create has done. - */ -static void chwall_domain_destroy(void *object_ssid, struct domain *d) -{ - int i, j; - struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY, - (struct acm_ssid_domain *) - object_ssid); - ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref; - - read_lock(&acm_bin_pol_rwlock); - - /* adjust running types set */ - for ( i = 0; i < chwall_bin_pol.max_types; i++ ) - chwall_bin_pol.running_types[i] -= - chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + i]; - - /* roll-back: re-adjust conflicting types aggregate */ - for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ ) - { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for ( j = 0; j < chwall_bin_pol.max_types; j++ ) - if ( chwall_bin_pol.conflict_sets[i * chwall_bin_pol.max_types + j] - && chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + j]) - { - common = 1; - break; - } - if ( common == 0 ) - { - /* try next conflict set, this one does not include - any type of chwall_ssidref */ - continue; - } - - /* now add types of the conflict set to conflict_aggregate_set - (except types in chwall_ssidref) */ - for ( j = 0; j < chwall_bin_pol.max_types; j++ ) - if ( chwall_bin_pol. - conflict_sets[i * chwall_bin_pol.max_types + j] - && !chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + j]) - chwall_bin_pol.conflict_aggregate_set[j]--; - } - - read_unlock(&acm_bin_pol_rwlock); - - return; -} - - -static int chwall_is_default_policy(void) -{ - static const domaintype_t def_policy[2] = { 0x0, 0x0 }; - return ( ( chwall_bin_pol.max_types == 1 ) && - ( chwall_bin_pol.max_ssidrefs == 2 ) && - ( memcmp(chwall_bin_pol.ssidrefs, - def_policy, - sizeof(def_policy)) == 0 ) ); -} - - -static int chwall_is_in_conflictset(ssidref_t ssidref1) -{ - /* is ssidref1 in conflict with any running domains ? */ - int rc = 0; - int i, j; - ssidref_t ssid_chwall; - - read_lock(&acm_bin_pol_rwlock); - - ssid_chwall = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref1); - - if ( ssid_chwall >= 0 && ssid_chwall < chwall_bin_pol.max_ssidrefs ) { - for ( i = 0; i < chwall_bin_pol.max_conflictsets && rc == 0; i++ ) { - for ( j = 0; j < chwall_bin_pol.max_types; j++ ) { - if ( chwall_bin_pol.conflict_aggregate_set - [i * chwall_bin_pol.max_types + j] && - chwall_bin_pol.ssidrefs - [ssid_chwall * chwall_bin_pol.max_types + j]) - { - rc = 1; - break; - } - } - } - } else { - rc = 1; - } - - read_unlock(&acm_bin_pol_rwlock); - - return rc; -} - - -struct acm_operations acm_chinesewall_ops = { - /* policy management services */ - .init_domain_ssid = chwall_init_domain_ssid, - .free_domain_ssid = chwall_free_domain_ssid, - .dump_binary_policy = chwall_dump_policy, - .test_binary_policy = chwall_test_policy, - .set_binary_policy = chwall_set_policy, - .dump_statistics = chwall_dump_stats, - .dump_ssid_types = chwall_dump_ssid_types, - /* domain management control hooks */ - .domain_create = chwall_domain_create, - .domain_destroy = chwall_domain_destroy, - /* event channel control hooks */ - .pre_eventchannel_unbound = NULL, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = NULL, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = NULL, - .fail_grant_map_ref = NULL, - .pre_grant_setup = NULL, - .fail_grant_setup = NULL, - /* generic domain-requested decision hooks */ - .sharing = NULL, - .authorization = NULL, - .conflictset = chwall_is_in_conflictset, - - .is_default_policy = chwall_is_default_policy, -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_core.c b/xen/xsm/acm/acm_core.c deleted file mode 100644 index b8b7b4f59c..0000000000 --- a/xen/xsm/acm/acm_core.c +++ /dev/null @@ -1,406 +0,0 @@ -#/**************************************************************** - * acm_core.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * Contributors: - * Stefan Berger <stefanb@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype access control module (ACM) - * This file handles initialization of the ACM - * as well as initializing/freeing security - * identifiers for domains (it calls on active - * policy hook functions). - * - */ - -#include <xen/config.h> -#include <xen/errno.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/delay.h> -#include <xen/sched.h> -#include <xen/multiboot.h> -#include <xsm/acm/acm_hooks.h> -#include <xsm/acm/acm_endian.h> -#include <xsm/xsm.h> - -/* debug: - * include/xsm/acm/acm_hooks.h defines a constant ACM_TRACE_MODE; - * define/undefine this constant to receive / suppress any - * security hook debug output of sHype - * - * include/xsm/acm/acm_hooks.h defines a constant ACM_DEBUG - * define/undefine this constant to receive non-hook-related - * debug output. - */ - -/* function prototypes */ -void acm_init_chwall_policy(void); -void acm_init_ste_policy(void); - -extern struct acm_operations acm_chinesewall_ops, - acm_simple_type_enforcement_ops, acm_null_ops; - -extern struct xsm_operations acm_xsm_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 */ -struct acm_operations *acm_secondary_ops = NULL; - -/* acm global binary policy (points to 'local' primary and secondary policies */ -struct acm_binary_policy acm_bin_pol; -/* acm binary policy lock */ -DEFINE_RWLOCK(acm_bin_pol_rwlock); - -/* ACM's only accepted policy name during boot */ -char polname[80]; -char *acm_accepted_boot_policy_name = NULL; - -/* a lits of all chained ssid structures */ -LIST_HEAD(ssid_list); -DEFINE_RWLOCK(ssid_list_rwlock); - -static void __init set_dom0_ssidref(const char *val) -{ - /* expected format: - ssidref=<hex number>:<policy name> - Policy name must not have a 'space'. - */ - const char *c; - int lo, hi; - int i; - int dom0_ssidref = simple_strtoull(val, &c, 0); - - if (!strncmp(&c[0],":ACM:", 5)) { - lo = dom0_ssidref & 0xffff; - if (lo < ACM_MAX_NUM_TYPES && lo >= 1) - dom0_chwall_ssidref = lo; - hi = dom0_ssidref >> 16; - if (hi < ACM_MAX_NUM_TYPES && hi >= 1) - dom0_ste_ssidref = hi; - for (i = 0; i < sizeof(polname); i++) { - polname[i] = c[5+i]; - if (polname[i] == '\0' || polname[i] == '\t' || - polname[i] == '\n' || polname[i] == ' ' || - polname[i] == ':') { - break; - } - } - polname[i] = 0; - acm_accepted_boot_policy_name = polname; - } -} - -custom_param("ssidref", set_dom0_ssidref); - -int -acm_set_policy_reference(u8 *buf, u32 buf_size) -{ - char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer)); - struct acm_policy_reference_buffer *pr = (struct acm_policy_reference_buffer *)buf; - - if (acm_accepted_boot_policy_name != NULL) { - if (strcmp(acm_accepted_boot_policy_name, name)) { - printk("Policy's name '%s' is not the expected one '%s'.\n", - name, acm_accepted_boot_policy_name); - return ACM_ERROR; - } - } - - acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, be32_to_cpu(pr->len)); - - if (!acm_bin_pol.policy_reference_name) - return -ENOMEM; - strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len)); - - printk("%s: Activating policy %s\n", __func__, - acm_bin_pol.policy_reference_name); - return 0; -} - -int -acm_dump_policy_reference(u8 *buf, u32 buf_size) -{ - struct acm_policy_reference_buffer *pr_buf = (struct acm_policy_reference_buffer *)buf; - int ret = sizeof(struct acm_policy_reference_buffer) + strlen(acm_bin_pol.policy_reference_name) + 1; - - ret = (ret + 7) & ~7; - if (buf_size < ret) - return -EINVAL; - - memset(buf, 0, ret); - pr_buf->len = cpu_to_be32(strlen(acm_bin_pol.policy_reference_name) + 1); /* including stringend '\0' */ - strlcpy((char *)(buf + sizeof(struct acm_policy_reference_buffer)), - acm_bin_pol.policy_reference_name, - be32_to_cpu(pr_buf->len)); - return ret; -} - -int -acm_init_binary_policy(u32 policy_code) -{ - 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; -} - -int -acm_is_policy(char *buf, unsigned long len) -{ - struct acm_policy_buffer *pol; - - if (buf == NULL || len < sizeof(struct acm_policy_buffer)) - return 0; - - pol = (struct acm_policy_buffer *)buf; - return be32_to_cpu(pol->magic) == ACM_MAGIC; -} - - -static int -acm_setup(char *policy_start, - unsigned long policy_len, - int is_bootpolicy) -{ - int rc = ACM_OK; - struct acm_policy_buffer *pol; - - if (policy_start == NULL || policy_len < sizeof(struct acm_policy_buffer)) - return rc; - - pol = (struct acm_policy_buffer *)policy_start; - if (be32_to_cpu(pol->magic) != ACM_MAGIC) - return rc; - - rc = do_acm_set_policy((void *)policy_start, (u32)policy_len, - is_bootpolicy, - NULL, NULL, NULL); - if (rc == ACM_OK) - { - printkd("Policy len 0x%lx, start at %p.\n",policy_len,policy_start); - } - else - { - printk("Invalid policy.\n"); - /* load default policy later */ - acm_active_security_policy = ACM_POLICY_UNDEFINED; - } - return rc; -} - - -int -acm_init(void) -{ - int ret = ACM_OK; - - printk("ACM-XSM: Initializing.\n"); - - /* first try to load the boot policy (uses its own locks) */ - acm_setup(policy_buffer, policy_size, 1); - - /* a user-provided policy may have any name; only matched during boot */ - acm_accepted_boot_policy_name = NULL; - - if (acm_active_security_policy != ACM_POLICY_UNDEFINED) - { - printk("%s: Enforcing %s boot policy.\n", __func__, - ACM_POLICY_NAME(acm_active_security_policy)); - 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)); - - /* (re-)set dom-0 ssidref to default */ - dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001; - - if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) { - ret = -EINVAL; - goto out; - } - acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY; - if (acm_active_security_policy != ACM_NULL_POLICY) - acm_bin_pol.policy_reference_name = "DEFAULT"; - else - acm_bin_pol.policy_reference_name = "NULL"; - - out: - if (ret != ACM_OK) - { - printk("%s: Error initializing policies.\n", __func__); - /* here one could imagine a clean panic */ - return -EINVAL; - } - - if (register_xsm(&acm_xsm_ops)) - panic("ACM-XSM: Unable to register with XSM.\n"); - - return ret; -} - -xsm_initcall(acm_init); - -int acm_init_domain_ssid(struct domain *subj, ssidref_t ssidref) -{ - struct acm_ssid_domain *ssid; - int ret1, ret2; - if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) - { - return ACM_INIT_SSID_ERROR; - } - - INIT_LIST_HEAD(&ssid->node); - ssid->datatype = ACM_DATATYPE_domain; - ssid->subject = subj; - ssid->domainid = subj->domain_id; - ssid->primary_ssid = NULL; - ssid->secondary_ssid = NULL; - - if (acm_active_security_policy != ACM_NULL_POLICY) - ssid->ssidref = ssidref; - else - ssid->ssidref = ACM_DEFAULT_SSID; - - subj->ssid = ssid; - /* now fill in primary and secondary parts; we only get here through hooks */ - if (acm_primary_ops->init_domain_ssid != NULL) - ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref); - else - ret1 = ACM_OK; - - if (acm_secondary_ops->init_domain_ssid != NULL) - ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref); - else - ret2 = ACM_OK; - - if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) - { - printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", - __func__, subj->domain_id); - acm_free_domain_ssid(subj); - return ACM_INIT_SSID_ERROR; - } - - printkd("%s: assigned domain %x the ssidref=%x.\n", - __func__, subj->domain_id, ssid->ssidref); - return ACM_OK; -} - - -void -acm_free_domain_ssid(struct domain *d) -{ - struct acm_ssid_domain *ssid = d->ssid; - - /* domain is already gone, just ssid is left */ - if (ssid == NULL) - return; - - ssid->subject = NULL; - if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ - acm_primary_ops->free_domain_ssid(ssid->primary_ssid); - ssid->primary_ssid = NULL; - if (acm_secondary_ops->free_domain_ssid != NULL) - acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); - ssid->secondary_ssid = NULL; - - xfree(ssid); - d->ssid = NULL; - - printkd("%s: Freed individual domain ssid (domain=%02x).\n", - __func__, id); -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_null_hooks.c b/xen/xsm/acm/acm_null_hooks.c deleted file mode 100644 index 440ee61bd8..0000000000 --- a/xen/xsm/acm/acm_null_hooks.c +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************** - * acm_null_hooks.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - */ - -#include <xsm/acm/acm_hooks.h> - -static int -null_init_domain_ssid(void **ssid, ssidref_t ssidref) -{ - return ACM_OK; -} - -static void -null_free_domain_ssid(void *ssid) -{ - return; -} - -static int -null_dump_binary_policy(u8 *buf, u32 buf_size) -{ - return 0; -} - -static int -null_test_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy, - struct acm_sized_buffer *errors) -{ - return ACM_OK; -} - -static int -null_set_binary_policy(u8 *buf, u32 buf_size) -{ - return ACM_OK; -} - -static int -null_dump_stats(u8 *buf, u16 buf_size) -{ - /* no stats for NULL policy */ - return 0; -} - -static int -null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size) -{ - /* no types */ - return 0; -} - - -/* now define the hook structure similarly to LSM */ -struct acm_operations acm_null_ops = { - .init_domain_ssid = null_init_domain_ssid, - .free_domain_ssid = null_free_domain_ssid, - .dump_binary_policy = null_dump_binary_policy, - .test_binary_policy = null_test_binary_policy, - .set_binary_policy = null_set_binary_policy, - .dump_statistics = null_dump_stats, - .dump_ssid_types = null_dump_ssid_types, - /* domain management control hooks */ - .domain_create = NULL, - .domain_destroy = NULL, - /* event channel control hooks */ - .pre_eventchannel_unbound = NULL, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = NULL, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = NULL, - .fail_grant_map_ref = NULL, - .pre_grant_setup = NULL, - .fail_grant_setup = NULL -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_ops.c b/xen/xsm/acm/acm_ops.c deleted file mode 100644 index 5836241a98..0000000000 --- a/xen/xsm/acm/acm_ops.c +++ /dev/null @@ -1,212 +0,0 @@ -/****************************************************************************** - * acm_ops.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * Process acm command requests from guest OS. - */ - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/mm.h> -#include <public/xsm/acm.h> -#include <public/xsm/acm_ops.h> -#include <xen/sched.h> -#include <xen/event.h> -#include <xen/trace.h> -#include <xen/console.h> -#include <xen/guest_access.h> -#include <xsm/acm/acm_hooks.h> - -#ifndef ACM_SECURITY - -long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) -{ - return -ENOSYS; -} - -#else - -int acm_authorize_acm_ops(struct domain *d) -{ - /* currently, policy management functions are restricted to privileged domains */ - return (IS_PRIV(d) ? 0 : -EPERM); -} - - -long do_acm_op(XEN_GUEST_HANDLE(xen_acmctl_t) u_acmctl) -{ - long rc = -EFAULT; - struct xen_acmctl curop, *op = &curop; - - if (acm_authorize_acm_ops(current->domain)) - return -EPERM; - - if ( copy_from_guest(op, u_acmctl, 1) ) - return -EFAULT; - - if (op->interface_version != ACM_INTERFACE_VERSION) - return -EACCES; - - switch ( op->cmd ) - { - - case ACMOP_setpolicy: { - rc = acm_set_policy(op->u.setpolicy.pushcache, - op->u.setpolicy.pushcache_size); - break; - } - - case ACMOP_getpolicy: { - rc = acm_get_policy(op->u.getpolicy.pullcache, - op->u.getpolicy.pullcache_size); - break; - } - - case ACMOP_dumpstats: { - rc = acm_dump_statistics(op->u.dumpstats.pullcache, - op->u.dumpstats.pullcache_size); - break; - } - - case ACMOP_getssid: { - ssidref_t ssidref; - - if (op->u.getssid.get_ssid_by == ACM_GETBY_ssidref) - ssidref = op->u.getssid.id.ssidref; - else if (op->u.getssid.get_ssid_by == ACM_GETBY_domainid) - { - struct domain *subj = rcu_lock_domain_by_id(op->u.getssid.id.domainid); - if (!subj) - { - rc = -ESRCH; /* domain not found */ - break; - } - if (subj->ssid == NULL) - { - rcu_unlock_domain(subj); - rc = -ESRCH; - break; - } - ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; - rcu_unlock_domain(subj); - } - else - { - rc = -ESRCH; - break; - } - rc = acm_get_ssid(ssidref, op->u.getssid.ssidbuf, - op->u.getssid.ssidbuf_size); - break; - } - - case ACMOP_getdecision: { - ssidref_t ssidref1, ssidref2; - - if (op->u.getdecision.get_decision_by1 == ACM_GETBY_ssidref) - ssidref1 = op->u.getdecision.id1.ssidref; - else if (op->u.getdecision.get_decision_by1 == ACM_GETBY_domainid) - { - struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id1.domainid); - if (!subj) - { - rc = -ESRCH; /* domain not found */ - break; - } - if (subj->ssid == NULL) - { - rcu_unlock_domain(subj); - rc = -ESRCH; - break; - } - ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; - rcu_unlock_domain(subj); - } - else - { - rc = -ESRCH; - break; - } - if (op->u.getdecision.get_decision_by2 == ACM_GETBY_ssidref) - ssidref2 = op->u.getdecision.id2.ssidref; - else if (op->u.getdecision.get_decision_by2 == ACM_GETBY_domainid) - { - struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id2.domainid); - if (!subj) - { - rc = -ESRCH; /* domain not found */ - break; - } - if (subj->ssid == NULL) - { - rcu_unlock_domain(subj); - rc = -ESRCH; - break; - } - ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; - rcu_unlock_domain(subj); - } - else - { - rc = -ESRCH; - break; - } - rc = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook); - - if (rc == ACM_ACCESS_PERMITTED) - { - op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED; - rc = 0; - } - else if (rc == ACM_ACCESS_DENIED) - { - op->u.getdecision.acm_decision = ACM_ACCESS_DENIED; - rc = 0; - } - else - rc = -ESRCH; - - if ( (rc == 0) && (copy_to_guest(u_acmctl, op, 1) != 0) ) - rc = -EFAULT; - break; - } - - case ACMOP_chgpolicy: { - rc = acm_change_policy(&op->u.change_policy); - break; - } - - case ACMOP_relabeldoms: { - rc = acm_relabel_domains(&op->u.relabel_doms); - break; - } - - default: - rc = -ENOSYS; - break; - } - - return rc; -} - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_policy.c b/xen/xsm/acm/acm_policy.c deleted file mode 100644 index 31219d9aae..0000000000 --- a/xen/xsm/acm/acm_policy.c +++ /dev/null @@ -1,893 +0,0 @@ -/**************************************************************** - * acm_policy.c - * - * Copyright (C) 2005-2007 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * Contributors: - * Stefan Berger <stefanb@watson.ibm.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype access control policy management for Xen. - * This interface allows policy tools in authorized - * domains to interact with the Xen access control module - * - */ - -#include <xen/config.h> -#include <xen/errno.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/delay.h> -#include <xen/sched.h> -#include <xen/guest_access.h> -#include <public/xen.h> -#include <xsm/acm/acm_core.h> -#include <public/xsm/acm_ops.h> -#include <xsm/acm/acm_hooks.h> -#include <xsm/acm/acm_endian.h> -#include <asm/current.h> - -static int acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels, - struct acm_sized_buffer *errors); -static void acm_doms_change_ssidref(ssidref_t (*translator) - (const struct acm_ssid_domain *, - const struct acm_sized_buffer *), - struct acm_sized_buffer *translation_map); -static void acm_doms_restore_ssidref(void); -static ssidref_t oldssid_to_newssid(const struct acm_ssid_domain *, - const struct acm_sized_buffer *map); - - -int -acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size) -{ - u8 *policy_buffer = NULL; - int ret = -EFAULT; - - if ( buf_size < sizeof(struct acm_policy_buffer) ) - return -EFAULT; - - /* copy buffer from guest domain */ - if ( (policy_buffer = xmalloc_array(u8, buf_size)) == NULL ) - return -ENOMEM; - - if ( copy_from_guest(policy_buffer, buf, buf_size) ) - { - printk("%s: Error copying!\n",__func__); - goto error_free; - } - ret = do_acm_set_policy(policy_buffer, buf_size, 0, - NULL, NULL, NULL); - - error_free: - xfree(policy_buffer); - return ret; -} - - -/* - * Update the policy of the running system by: - * - deleting ssidrefs that are not in the new policy anymore - * -> no running domain may use such an ssidref - * - assign new ssidrefs to domains based on their old ssidrefs - * - */ -static int -_acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy, - struct acm_policy_buffer *pol, - struct acm_sized_buffer *deletions, - struct acm_sized_buffer *ssidchanges, - struct acm_sized_buffer *errors) -{ - uint32_t offset, length; - static int require_update = 0; - - write_lock(&acm_bin_pol_rwlock); - - if ( require_update != 0 && - ( deletions == NULL || ssidchanges == NULL ) ) - goto error_lock_free; - - require_update = 1; - /* - first some tests to check compatibility of new policy with - current state of system/domains - */ - - /* if ssidrefs are to be deleted, make sure no domain is using them */ - if ( deletions != NULL ) - if ( acm_check_deleted_ssidrefs(deletions, errors) ) - goto error_lock_free_nossidchange; - - if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) ) - /* assign all running domains new ssidrefs as requested */ - acm_doms_change_ssidref(oldssid_to_newssid, ssidchanges); - - /* test primary policy data with the new ssidrefs */ - offset = be32_to_cpu(pol->primary_buffer_offset); - length = be32_to_cpu(pol->secondary_buffer_offset) - offset; - - if ( (offset + length) > buf_size || - acm_primary_ops->test_binary_policy(buf + offset, length, - is_bootpolicy, - errors)) - goto error_lock_free; - - /* test secondary policy data with the new ssidrefs */ - offset = be32_to_cpu(pol->secondary_buffer_offset); - length = be32_to_cpu(pol->len) - offset; - if ( (offset + length) > buf_size || - acm_secondary_ops->test_binary_policy(buf + offset, length, - is_bootpolicy, - errors)) - goto error_lock_free; - - /* end of testing --- now real updates */ - - offset = be32_to_cpu(pol->policy_reference_offset); - length = be32_to_cpu(pol->primary_buffer_offset) - offset; - - /* set label reference name */ - if ( (offset + length) > buf_size || - acm_set_policy_reference(buf + offset, length) ) - goto error_lock_free; - - /* set primary policy data */ - offset = be32_to_cpu(pol->primary_buffer_offset); - length = be32_to_cpu(pol->secondary_buffer_offset) - offset; - - if ( acm_primary_ops->set_binary_policy(buf + offset, length) ) - goto error_lock_free; - - /* set secondary policy data */ - offset = be32_to_cpu(pol->secondary_buffer_offset); - length = be32_to_cpu(pol->len) - offset; - if ( acm_secondary_ops->set_binary_policy(buf + offset, length) ) - goto error_lock_free; - - memcpy(&acm_bin_pol.xml_pol_version, - &pol->xml_pol_version, - sizeof(acm_bin_pol.xml_pol_version)); - - memcpy(&acm_bin_pol.xml_policy_hash, - pol->xml_policy_hash, - sizeof(acm_bin_pol.xml_policy_hash)); - - if ( acm_primary_ops->is_default_policy() && - acm_secondary_ops->is_default_policy() ) - require_update = 0; - - write_unlock(&acm_bin_pol_rwlock); - - return ACM_OK; - -error_lock_free: - if ( (ssidchanges != NULL) && (ssidchanges->num_items > 0) ) - { - acm_doms_restore_ssidref(); - } -error_lock_free_nossidchange: - do_chwall_init_state_curr(NULL); - write_unlock(&acm_bin_pol_rwlock); - - return -EFAULT; -} - - -int -do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy, - struct acm_sized_buffer *deletions, - struct acm_sized_buffer *ssidchanges, - struct acm_sized_buffer *errors) -{ - struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf; - - /* some sanity checking */ - if ( (be32_to_cpu(pol->magic) != ACM_MAGIC) || - (buf_size != be32_to_cpu(pol->len)) || - (be32_to_cpu(pol->policy_version) != ACM_POLICY_VERSION) ) - { - printk("%s: ERROR in Magic, Version, or buf size.\n", __func__); - goto error_free; - } - - if ( acm_active_security_policy == ACM_POLICY_UNDEFINED ) - { - /* setup the policy with the boot policy */ - if ( acm_init_binary_policy( - (be32_to_cpu(pol->secondary_policy_code) << 4) | - be32_to_cpu(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 ( (be32_to_cpu(pol->primary_policy_code) != - acm_bin_pol.primary_policy_code) || - (be32_to_cpu(pol->secondary_policy_code) != - acm_bin_pol.secondary_policy_code) ) - { - printkd("%s: Wrong policy type in boot policy!\n", __func__); - goto error_free; - } - - return _acm_update_policy(buf, buf_size, is_bootpolicy, - pol, - deletions, ssidchanges, - errors); - - error_free: - printk("%s: Error setting policy.\n", __func__); - return -EFAULT; -} - -int -acm_get_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size) -{ - u8 *policy_buffer; - int ret; - struct acm_policy_buffer *bin_pol; - - if ( buf_size < sizeof(struct acm_policy_buffer) ) - return -EFAULT; - - if ( (policy_buffer = xmalloc_array(u8, buf_size)) == NULL ) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); - - bin_pol = (struct acm_policy_buffer *)policy_buffer; - bin_pol->magic = cpu_to_be32(ACM_MAGIC); - bin_pol->primary_policy_code = - cpu_to_be32(acm_bin_pol.primary_policy_code); - bin_pol->secondary_policy_code = - cpu_to_be32(acm_bin_pol.secondary_policy_code); - - bin_pol->len = cpu_to_be32(sizeof(struct acm_policy_buffer)); - bin_pol->policy_reference_offset = cpu_to_be32(be32_to_cpu(bin_pol->len)); - bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len)); - bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len)); - - memcpy(&bin_pol->xml_pol_version, - &acm_bin_pol.xml_pol_version, - sizeof(struct acm_policy_version)); - - memcpy(&bin_pol->xml_policy_hash, - &acm_bin_pol.xml_policy_hash, - sizeof(acm_bin_pol.xml_policy_hash)); - - ret = acm_dump_policy_reference( - policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset), - buf_size - be32_to_cpu(bin_pol->policy_reference_offset)); - - if ( ret < 0 ) - goto error_free_unlock; - - bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret); - bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len)); - - ret = acm_primary_ops->dump_binary_policy( - policy_buffer + be32_to_cpu(bin_pol->primary_buffer_offset), - buf_size - be32_to_cpu(bin_pol->primary_buffer_offset)); - - if ( ret < 0 ) - goto error_free_unlock; - - bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret); - bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len)); - - ret = acm_secondary_ops->dump_binary_policy( - policy_buffer + be32_to_cpu(bin_pol->secondary_buffer_offset), - buf_size - be32_to_cpu(bin_pol->secondary_buffer_offset)); - - if ( ret < 0 ) - goto error_free_unlock; - - bin_pol->len = cpu_to_be32(be32_to_cpu(bin_pol->len) + ret); - if ( copy_to_guest(buf, policy_buffer, be32_to_cpu(bin_pol->len)) ) - goto error_free_unlock; - - read_unlock(&acm_bin_pol_rwlock); - xfree(policy_buffer); - - return ACM_OK; - - error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting policy.\n", __func__); - xfree(policy_buffer); - - return -EFAULT; -} - -int -acm_dump_statistics(XEN_GUEST_HANDLE_64(void) buf, u16 buf_size) -{ - /* send stats to user space */ - u8 *stats_buffer; - int len1, len2; - struct acm_stats_buffer acm_stats; - - if ( (stats_buffer = xmalloc_array(u8, buf_size)) == NULL ) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); - - len1 = acm_primary_ops->dump_statistics( - stats_buffer + sizeof(struct acm_stats_buffer), - buf_size - sizeof(struct acm_stats_buffer)); - if ( len1 < 0 ) - goto error_lock_free; - - len2 = acm_secondary_ops->dump_statistics( - stats_buffer + sizeof(struct acm_stats_buffer) + len1, - buf_size - sizeof(struct acm_stats_buffer) - len1); - if ( len2 < 0 ) - goto error_lock_free; - - acm_stats.magic = cpu_to_be32(ACM_MAGIC); - acm_stats.primary_policy_code = - cpu_to_be32(acm_bin_pol.primary_policy_code); - acm_stats.secondary_policy_code = - cpu_to_be32(acm_bin_pol.secondary_policy_code); - acm_stats.primary_stats_offset = - cpu_to_be32(sizeof(struct acm_stats_buffer)); - acm_stats.secondary_stats_offset = - cpu_to_be32(sizeof(struct acm_stats_buffer) + len1); - acm_stats.len = cpu_to_be32(sizeof(struct acm_stats_buffer) + len1 + len2); - - memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer)); - - if ( copy_to_guest(buf, - stats_buffer, - sizeof(struct acm_stats_buffer) + len1 + len2) ) - goto error_lock_free; - - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - - return ACM_OK; - - error_lock_free: - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - - return -EFAULT; -} - - -int -acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE_64(void) buf, u16 buf_size) -{ - /* send stats to user space */ - u8 *ssid_buffer; - int ret; - struct acm_ssid_buffer *acm_ssid; - if ( buf_size < sizeof(struct acm_ssid_buffer) ) - return -EFAULT; - - if ( (ssid_buffer = xmalloc_array(u8, buf_size)) == NULL ) - return -ENOMEM; - - read_lock(&acm_bin_pol_rwlock); - - acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; - acm_ssid->len = sizeof(struct acm_ssid_buffer); - acm_ssid->ssidref = ssidref; - acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; - acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; - - acm_ssid->policy_reference_offset = acm_ssid->len; - ret = acm_dump_policy_reference( - ssid_buffer + acm_ssid->policy_reference_offset, - buf_size - acm_ssid->policy_reference_offset); - if ( ret < 0 ) - goto error_free_unlock; - - acm_ssid->len += ret; - acm_ssid->primary_types_offset = acm_ssid->len; - - /* ret >= 0 --> ret == max_types */ - ret = acm_primary_ops->dump_ssid_types( - ACM_PRIMARY(ssidref), - ssid_buffer + acm_ssid->primary_types_offset, - buf_size - acm_ssid->primary_types_offset); - if ( ret < 0 ) - goto error_free_unlock; - - acm_ssid->len += ret; - acm_ssid->primary_max_types = ret; - acm_ssid->secondary_types_offset = acm_ssid->len; - - ret = acm_secondary_ops->dump_ssid_types( - ACM_SECONDARY(ssidref), - ssid_buffer + acm_ssid->secondary_types_offset, - buf_size - acm_ssid->secondary_types_offset); - if ( ret < 0 ) - goto error_free_unlock; - - acm_ssid->len += ret; - acm_ssid->secondary_max_types = ret; - - if ( copy_to_guest(buf, ssid_buffer, acm_ssid->len) ) - goto error_free_unlock; - - read_unlock(&acm_bin_pol_rwlock); - xfree(ssid_buffer); - - return ACM_OK; - - error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting ssid.\n", __func__); - xfree(ssid_buffer); - - return -ENOMEM; -} - -int -acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook) -{ - int ret = ACM_ACCESS_DENIED; - - read_lock(&acm_bin_pol_rwlock); - - switch ( hook ) - { - - case ACMHOOK_sharing: - /* Sharing hook restricts access in STE policy only */ - ret = acm_sharing(ssidref1, ssidref2); - break; - - case ACMHOOK_authorization: - ret = acm_authorization(ssidref1, ssidref2); - break; - - case ACMHOOK_conflictset: - ret = acm_conflictset(ssidref1); - - default: - /* deny */ - break; - } - - read_unlock(&acm_bin_pol_rwlock); - - printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n", - __func__, ssidref1, ssidref2, - (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED"); - - return ret; -} - - - -/* - Check if an ssidref of the current policy type is being used by any - domain. - */ -static int -acm_check_used_ssidref(uint32_t policy_type, uint32_t search_ssidref, - struct acm_sized_buffer *errors) -{ - int rc = 0; - struct acm_ssid_domain *rawssid; - - read_lock(&ssid_list_rwlock); - - for_each_acmssid( rawssid ) - { - ssidref_t ssidref; - void *s = GET_SSIDP(policy_type, rawssid); - - if ( policy_type == ACM_CHINESE_WALL_POLICY ) - { - ssidref = ((struct chwall_ssid *)s)->chwall_ssidref; - } else { - ssidref = ((struct ste_ssid *)s)->ste_ssidref; - } - gdprintk(XENLOG_INFO,"domid=%d: search ssidref=%d, ssidref=%d\n", - rawssid->domainid,search_ssidref,ssidref); - if ( ssidref == search_ssidref ) - { - /* one is enough */ - acm_array_append_tuple(errors, ACM_SSIDREF_IN_USE, search_ssidref); - rc = 1; - break; - } - } - - read_unlock(&ssid_list_rwlock); - - return rc; -} - - -/* - * Translate a current ssidref into its future representation under - * the new policy. - * The map provides translation of ssidrefs from old to new in tuples - * of (old ssidref, new ssidref). - */ -static ssidref_t -oldssid_to_newssid(const struct acm_ssid_domain *rawssid, - const struct acm_sized_buffer *map) -{ - uint i; - - if ( rawssid != NULL ) - { - ssidref_t ssid = rawssid->ssidref & 0xffff; - for ( i = 0; i + 1 < map->num_items; i += 2 ) - { - if ( map->array[i] == ssid ) - { - return (map->array[i+1] << 16 | map->array[i+1]); - } - } - } - return ACM_INVALID_SSIDREF; -} - - -/* - * Assign an ssidref to the CHWALL policy component of the domain - */ -static void -acm_pri_policy_assign_ssidref(struct acm_ssid_domain *rawssid, - ssidref_t new_ssid) -{ - struct chwall_ssid *chwall = (struct chwall_ssid *)rawssid->primary_ssid; - chwall->chwall_ssidref = new_ssid; -} - - -/* - * Assign an ssidref to the STE policy component of the domain - */ -static void -acm_sec_policy_assign_ssidref(struct acm_ssid_domain *rawssid, - ssidref_t new_ssid) -{ - struct ste_ssid *ste = (struct ste_ssid *)rawssid->secondary_ssid; - ste->ste_ssidref = new_ssid; -} - -/* - Change the ssidrefs on each domain using a passed translation function; - */ -static void -acm_doms_change_ssidref(ssidref_t (*translator_fn) - (const struct acm_ssid_domain *, - const struct acm_sized_buffer *), - struct acm_sized_buffer *translation_map) -{ - struct acm_ssid_domain *rawssid; - - write_lock(&ssid_list_rwlock); - - for_each_acmssid( rawssid ) - { - ssidref_t new_ssid; - - rawssid->old_ssidref = rawssid->ssidref; - - new_ssid = translator_fn(rawssid, translation_map); - if ( new_ssid == ACM_INVALID_SSIDREF ) - { - /* means no mapping found, so no change -- old = new */ - continue; - } - - acm_pri_policy_assign_ssidref(rawssid, ACM_PRIMARY (new_ssid) ); - acm_sec_policy_assign_ssidref(rawssid, ACM_SECONDARY(new_ssid) ); - - rawssid->ssidref = new_ssid; - } - - write_unlock(&ssid_list_rwlock); -} - -/* - * Restore the previous ssidref values on all domains - */ -static void -acm_doms_restore_ssidref(void) -{ - struct acm_ssid_domain *rawssid; - - write_lock(&ssid_list_rwlock); - - for_each_acmssid( rawssid ) - { - ssidref_t old_ssid; - - if ( rawssid->old_ssidref == rawssid->ssidref ) - continue; - - old_ssid = rawssid->old_ssidref & 0xffff; - rawssid->ssidref = rawssid->old_ssidref; - - acm_pri_policy_assign_ssidref(rawssid, old_ssid); - acm_sec_policy_assign_ssidref(rawssid, old_ssid); - } - - write_unlock(&ssid_list_rwlock); -} - - -/* - Check the list of domains whether either one of them uses a - to-be-deleted ssidref. - */ -static int -acm_check_deleted_ssidrefs(struct acm_sized_buffer *dels, - struct acm_sized_buffer *errors) -{ - int rc = 0; - uint idx; - /* check for running domains that should not be there anymore */ - for ( idx = 0; idx < dels->num_items; idx++ ) - { - if ( acm_check_used_ssidref(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - dels->array[idx], - errors) > 0 || - acm_check_used_ssidref(ACM_CHINESE_WALL_POLICY, - dels->array[idx], - errors) > 0) - { - rc = ACM_ERROR; - break; - } - } - return rc; -} - - -/* - * Change the policy of the system. - */ -int -acm_change_policy(struct acm_change_policy *chgpolicy) -{ - int rc = 0; - u8 *binpolicy = NULL; - struct acm_sized_buffer dels = - { - .array = NULL, - }; - struct acm_sized_buffer ssidmap = - { - .array = NULL, - }; - struct acm_sized_buffer errors = - { - .array = NULL, - }; - - gdprintk(XENLOG_INFO, "change policy operation\n"); - - if ( (chgpolicy->delarray_size > 4096) || - (chgpolicy->chgarray_size > 4096) || - (chgpolicy->errarray_size > 4096)) - { - return ACM_ERROR; - } - - dels.num_items = chgpolicy->delarray_size / sizeof(uint32_t); - if ( dels.num_items > 0 ) - { - dels.array = xmalloc_array(uint32_t, dels.num_items); - if ( dels.array == NULL ) - { - rc = -ENOMEM; - goto acm_chg_policy_exit; - } - } - - ssidmap.num_items = chgpolicy->chgarray_size / sizeof(uint32_t); - if ( ssidmap.num_items > 0 ) - { - ssidmap.array = xmalloc_array(uint32_t, ssidmap.num_items); - if ( ssidmap.array == NULL ) - { - rc = -ENOMEM; - goto acm_chg_policy_exit; - } - } - - errors.num_items = chgpolicy->errarray_size / sizeof(uint32_t); - if ( errors.num_items > 0 ) - { - errors.array = xmalloc_array(uint32_t, errors.num_items); - if ( errors.array == NULL ) - { - rc = -ENOMEM; - goto acm_chg_policy_exit; - } - memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items); - } - - binpolicy = xmalloc_array(u8, - chgpolicy->policy_pushcache_size); - if ( binpolicy == NULL ) - { - rc = -ENOMEM; - goto acm_chg_policy_exit; - } - - if ( copy_from_guest(dels.array, - chgpolicy->del_array, - dels.num_items) || - copy_from_guest(ssidmap.array, - chgpolicy->chg_array, - ssidmap.num_items) || - copy_from_guest(binpolicy, - chgpolicy->policy_pushcache, - chgpolicy->policy_pushcache_size )) - { - rc = -EFAULT; - goto acm_chg_policy_exit; - } - - rc = do_acm_set_policy(binpolicy, - chgpolicy->policy_pushcache_size, - 0, - &dels, &ssidmap, &errors); - - if ( (errors.num_items > 0) && - copy_to_guest(chgpolicy->err_array, - errors.array, - errors.num_items ) ) - { - rc = -EFAULT; - goto acm_chg_policy_exit; - } - - -acm_chg_policy_exit: - xfree(dels.array); - xfree(ssidmap.array); - xfree(errors.array); - xfree(binpolicy); - - return rc; -} - - -/* - * Lookup the new ssidref given the domain's id. - * The translation map provides a list of tuples in the format - * (domid, new ssidref). - */ -static ssidref_t -domid_to_newssid(const struct acm_ssid_domain *rawssid, - const struct acm_sized_buffer *map) -{ - domid_t domid = rawssid->domainid; - uint i; - for ( i = 0; (i+1) < map->num_items; i += 2 ) - { - if ( map->array[i] == domid ) - return (ssidref_t)map->array[i+1]; - } - return ACM_INVALID_SSIDREF; -} - - -int -do_acm_relabel_doms(struct acm_sized_buffer *relabel_map, - struct acm_sized_buffer *errors) -{ - int rc = 0, irc; - - write_lock(&acm_bin_pol_rwlock); - - acm_doms_change_ssidref(domid_to_newssid, relabel_map); - - /* run tests; collect as much error info as possible */ - irc = do_chwall_init_state_curr(errors); - irc += do_ste_init_state_curr(errors); - if ( irc != 0 ) - { - rc = -EFAULT; - goto acm_relabel_doms_lock_err_exit; - } - - write_unlock(&acm_bin_pol_rwlock); - - return rc; - -acm_relabel_doms_lock_err_exit: - /* revert the new ssidref assignment */ - acm_doms_restore_ssidref(); - do_chwall_init_state_curr(NULL); - - write_unlock(&acm_bin_pol_rwlock); - - return rc; -} - - -int -acm_relabel_domains(struct acm_relabel_doms *relabel) -{ - int rc = ACM_OK; - struct acm_sized_buffer relabels = - { - .array = NULL, - }; - struct acm_sized_buffer errors = - { - .array = NULL, - }; - - if ( relabel->relabel_map_size > 4096 ) - { - return ACM_ERROR; - } - - relabels.num_items = relabel->relabel_map_size / sizeof(uint32_t); - if ( relabels.num_items > 0 ) - { - relabels.array = xmalloc_array(uint32_t, relabels.num_items); - if ( relabels.array == NULL ) - { - rc = -ENOMEM; - goto acm_relabel_doms_exit; - } - } - - errors.num_items = relabel->errarray_size / sizeof(uint32_t); - if ( errors.num_items > 0 ) - { - errors.array = xmalloc_array(uint32_t, errors.num_items); - if ( errors.array == NULL ) - { - rc = -ENOMEM; - goto acm_relabel_doms_exit; - } - memset(errors.array, 0x0, sizeof(uint32_t) * errors.num_items); - } - - if ( copy_from_guest(relabels.array, - relabel->relabel_map, - relabels.num_items) ) - { - rc = -EFAULT; - goto acm_relabel_doms_exit; - } - - rc = do_acm_relabel_doms(&relabels, &errors); - - if ( copy_to_guest(relabel->err_array, - errors.array, - errors.num_items ) ) - rc = -EFAULT; - -acm_relabel_doms_exit: - xfree(relabels.array); - xfree(errors.array); - return rc; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_simple_type_enforcement_hooks.c b/xen/xsm/acm/acm_simple_type_enforcement_hooks.c deleted file mode 100644 index 1ceb89fb9c..0000000000 --- a/xen/xsm/acm/acm_simple_type_enforcement_hooks.c +++ /dev/null @@ -1,924 +0,0 @@ -/**************************************************************** - * acm_simple_type_enforcement_hooks.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * Contributors: - * Stefan Berger <stefanb@watson.ibm.com> - * support for network order binary policies - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * sHype Simple Type Enforcement for Xen - * STE allows to control which domains can setup sharing - * (eventchannels right now) with which other domains. Hooks - * are defined and called throughout Xen when domains bind to - * shared resources (setup eventchannels) and a domain is allowed - * to setup sharing with another domain if and only if both domains - * share at least on common type. - * - */ - -#include <xen/lib.h> -#include <asm/types.h> -#include <asm/current.h> -#include <asm/atomic.h> -#include <xsm/acm/acm_hooks.h> -#include <xsm/acm/acm_endian.h> -#include <xsm/acm/acm_core.h> - -ssidref_t dom0_ste_ssidref = 0x0001; - -/* local cache structures for STE policy */ -struct ste_binary_policy ste_bin_pol; - -static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) -{ - int i; - - if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs && - ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs ) - { - for( i = 0; i< ste_bin_pol.max_types; i++ ) - if ( ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] && - ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i]) - { - printkd("%s: common type #%02x.\n", __func__, i); - return 1; - } - } - return 0; -} - -static inline int is_superset(ssidref_t ref1, ssidref_t ref2) -{ - int i; - - if ( ref1 >= 0 && ref1 < ste_bin_pol.max_ssidrefs && - ref2 >= 0 && ref2 < ste_bin_pol.max_ssidrefs ) - { - for( i = 0; i< ste_bin_pol.max_types; i++ ) - if (!ste_bin_pol.ssidrefs[ref1 * ste_bin_pol.max_types + i] && - ste_bin_pol.ssidrefs[ref2 * ste_bin_pol.max_types + i]) - { - return 0; - } - } else { - return 0; - } - return 1; -} - - -/* Helper function: return = (subj and obj share a common type) */ -static int share_common_type(struct domain *subj, struct domain *obj) -{ - ssidref_t ref_s, ref_o; - int ret; - - if ( (subj == NULL) || (obj == NULL) || - (subj->ssid == NULL) || (obj->ssid == NULL) ) - return 0; - - read_lock(&acm_bin_pol_rwlock); - - /* lookup the policy-local ssids */ - ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref; - ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref; - /* check whether subj and obj share a common ste type */ - ret = have_common_type(ref_s, ref_o); - - read_unlock(&acm_bin_pol_rwlock); - - return ret; -} - -/* - * Initializing STE policy (will be filled by policy partition - * using setpolicy command) - */ -int acm_init_ste_policy(void) -{ - /* minimal startup policy; policy write-locked already */ - ste_bin_pol.max_types = 2; - ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref; - ste_bin_pol.ssidrefs = - (domaintype_t *)xmalloc_array(domaintype_t, - ste_bin_pol.max_types * - ste_bin_pol.max_ssidrefs); - - if (ste_bin_pol.ssidrefs == NULL) - return ACM_INIT_SSID_ERROR; - - memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) * - ste_bin_pol.max_types * - ste_bin_pol.max_ssidrefs); - - /* initialize state so that dom0 can start up and communicate with itself */ - ste_bin_pol.ssidrefs[ste_bin_pol.max_types - 1 ] = 1; - ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1; - ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref + 1] = 1; - - /* init stats */ - atomic_set(&(ste_bin_pol.ec_eval_count), 0); - atomic_set(&(ste_bin_pol.ec_denied_count), 0); - atomic_set(&(ste_bin_pol.ec_cachehit_count), 0); - atomic_set(&(ste_bin_pol.gt_eval_count), 0); - atomic_set(&(ste_bin_pol.gt_denied_count), 0); - atomic_set(&(ste_bin_pol.gt_cachehit_count), 0); - - return ACM_OK; -} - - -/* ste initialization function hooks */ -static int -ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref) -{ - int i; - struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); - - if ( ste_ssidp == NULL ) - return ACM_INIT_SSID_ERROR; - - /* get policy-local ssid reference */ - ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - ssidref); - - if ( (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) ) - { - printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n", - __func__, ste_ssidp->ste_ssidref); - xfree(ste_ssidp); - return ACM_INIT_SSID_ERROR; - } - /* clean ste cache */ - for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ ) - ste_ssidp->ste_cache[i].valid = ACM_STE_free; - - (*ste_ssid) = ste_ssidp; - printkd("%s: determined ste_ssidref to %x.\n", - __func__, ste_ssidp->ste_ssidref); - - return ACM_OK; -} - - -static void -ste_free_domain_ssid(void *ste_ssid) -{ - xfree(ste_ssid); - return; -} - -/* dump type enforcement cache; policy read-locked already */ -static int -ste_dump_policy(u8 *buf, u32 buf_size) { - struct acm_ste_policy_buffer *ste_buf = - (struct acm_ste_policy_buffer *)buf; - int ret = 0; - - if ( buf_size < sizeof(struct acm_ste_policy_buffer) ) - return -EINVAL; - - ste_buf->ste_max_types = cpu_to_be32(ste_bin_pol.max_types); - ste_buf->ste_max_ssidrefs = cpu_to_be32(ste_bin_pol.max_ssidrefs); - ste_buf->policy_code = cpu_to_be32(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); - ste_buf->ste_ssid_offset = - cpu_to_be32(sizeof(struct acm_ste_policy_buffer)); - ret = be32_to_cpu(ste_buf->ste_ssid_offset) + - sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types; - - ret = (ret + 7) & ~7; - - if (buf_size < ret) - return -EINVAL; - - /* now copy buffer over */ - arrcpy(buf + be32_to_cpu(ste_buf->ste_ssid_offset), - ste_bin_pol.ssidrefs, - sizeof(domaintype_t), - ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types); - - return ret; -} - -/* - * ste_init_state is called when a policy is changed to detect violations - * (return != 0). from a security point of view, we simulate that all - * running domains are re-started and all sharing decisions are replayed - * to detect violations or current sharing behavior (right now: - * event_channels, future: also grant_tables) - */ -static int -ste_init_state(struct acm_sized_buffer *errors) -{ - int violation = 1; - struct ste_ssid *ste_ssid, *ste_rssid; - ssidref_t ste_ssidref, ste_rssidref; - struct domain *d, *rdom; - domid_t rdomid; - struct active_grant_entry *act; - int port, i; - - rcu_read_lock(&domlist_read_lock); - read_lock(&ssid_list_rwlock); - - /* go through all domains and adjust policy as if this domain was - started now */ - - for_each_domain ( d ) - { - struct evtchn *ports; - unsigned int bucket; - - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)d->ssid); - ste_ssidref = ste_ssid->ste_ssidref; - traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n", - __func__, d->domain_id, ste_ssidref); - /* a) check for event channel conflicts */ - for ( bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++ ) - { - spin_lock(&d->event_lock); - ports = d->evtchn[bucket]; - if ( ports == NULL) - { - spin_unlock(&d->event_lock); - break; - } - - for ( port = 0; port < EVTCHNS_PER_BUCKET; port++ ) - { - if ( ports[port].state == ECS_INTERDOMAIN ) - { - rdom = ports[port].u.interdomain.remote_dom; - rdomid = rdom->domain_id; - } else { - continue; /* port unused */ - } - - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - traceprintk("%s: eventch: domain %x (ssidref %x) --> " - "domain %x (rssidref %x) used (port %x).\n", - __func__, d->domain_id, ste_ssidref, - rdom->domain_id, ste_rssidref, port); - /* check whether on subj->ssid, obj->ssid share a common type*/ - if ( ! have_common_type(ste_ssidref, ste_rssidref) ) - { - printkd("%s: Policy violation in event channel domain " - "%x -> domain %x.\n", - __func__, d->domain_id, rdomid); - spin_unlock(&d->event_lock); - - acm_array_append_tuple(errors, - ACM_EVTCHN_SHARING_VIOLATION, - d->domain_id << 16 | rdomid); - goto out; - } - } - spin_unlock(&d->event_lock); - } - - - /* b) check for grant table conflicts on shared pages */ - spin_lock(&d->grant_table->lock); - for ( i = 0; i < nr_active_grant_frames(d->grant_table); i++ ) - { -#define APP (PAGE_SIZE / sizeof(struct active_grant_entry)) - act = &d->grant_table->active[i/APP][i%APP]; - if ( act->pin != 0 ) { - printkd("%s: grant dom (%hu) SHARED (%d) pin (%d) " - "dom:(%hu) frame:(%lx)\n", - __func__, d->domain_id, i, act->pin, - act->domid, (unsigned long)act->frame); - rdomid = act->domid; - if ( (rdom = rcu_lock_domain_by_id(rdomid)) == NULL ) - { - spin_unlock(&d->grant_table->lock); - printkd("%s: domain not found ERROR!\n", __func__); - - acm_array_append_tuple(errors, - ACM_DOMAIN_LOOKUP, - rdomid); - goto out; - } - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - rcu_unlock_domain(rdom); - if ( ! have_common_type(ste_ssidref, ste_rssidref) ) - { - spin_unlock(&d->grant_table->lock); - printkd("%s: Policy violation in grant table " - "sharing domain %x -> domain %x.\n", - __func__, d->domain_id, rdomid); - - acm_array_append_tuple(errors, - ACM_GNTTAB_SHARING_VIOLATION, - d->domain_id << 16 | rdomid); - goto out; - } - } - } - spin_unlock(&d->grant_table->lock); - } - violation = 0; - out: - read_unlock(&ssid_list_rwlock); - rcu_read_unlock(&domlist_read_lock); - return violation; - /* - returning "violation != 0" means that existing sharing between domains - would not have been allowed if the new policy had been enforced before - the sharing; for ste, this means that there are at least 2 domains - that have established sharing through event-channels or grant-tables - but these two domains don't have no longer a common type in their - typesets referenced by their ssidrefs - */ -} - - -/* - * Call ste_init_state with the current policy. - */ -int -do_ste_init_state_curr(struct acm_sized_buffer *errors) -{ - return ste_init_state(errors); -} - - -/* set new policy; policy write-locked already */ -static int -_ste_update_policy(u8 *buf, u32 buf_size, int test_only, - struct acm_sized_buffer *errors) -{ - int rc = -EFAULT; - struct acm_ste_policy_buffer *ste_buf = - (struct acm_ste_policy_buffer *)buf; - void *ssidrefsbuf; - struct ste_ssid *ste_ssid; - struct acm_ssid_domain *rawssid; - int i; - - - /* 1. create and copy-in new ssidrefs buffer */ - ssidrefsbuf = xmalloc_array(u8, - sizeof(domaintype_t) * - ste_buf->ste_max_types * - ste_buf->ste_max_ssidrefs); - if ( ssidrefsbuf == NULL ) { - return -ENOMEM; - } - if ( ste_buf->ste_ssid_offset + - sizeof(domaintype_t) * - ste_buf->ste_max_ssidrefs * - ste_buf->ste_max_types > buf_size ) - goto error_free; - - arrcpy(ssidrefsbuf, - buf + ste_buf->ste_ssid_offset, - sizeof(domaintype_t), - ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types); - - - /* - * 3. in test mode: re-calculate sharing decisions based on running - * domains; this can fail if new policy is conflicting with sharing - * of running domains - * now: reject violating new policy; future: adjust sharing through - * revoking sharing - */ - - if ( test_only ) { - /* temporarily replace old policy with new one for the testing */ - struct ste_binary_policy orig_ste_bin_pol = ste_bin_pol; - ste_bin_pol.max_types = ste_buf->ste_max_types; - ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; - ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; - - if ( ste_init_state(errors) ) - { - /* new policy conflicts with sharing of running domains */ - printk("%s: New policy conflicts with running domains. " - "Policy load aborted.\n", __func__); - } else { - rc = ACM_OK; - } - /* revert changes, no matter whether testing was successful or not */ - ste_bin_pol = orig_ste_bin_pol; - goto error_free; - } - - /* 3. replace old policy (activate new policy) */ - ste_bin_pol.max_types = ste_buf->ste_max_types; - ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; - xfree(ste_bin_pol.ssidrefs); - ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; - - /* clear all ste caches */ - read_lock(&ssid_list_rwlock); - - for_each_acmssid( rawssid ) - { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid); - for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ ) - ste_ssid->ste_cache[i].valid = ACM_STE_free; - } - - read_unlock(&ssid_list_rwlock); - - return ACM_OK; - - error_free: - if ( !test_only ) - printk("%s: ERROR setting policy.\n", __func__); - xfree(ssidrefsbuf); - return rc; -} - -static int -ste_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy, - struct acm_sized_buffer *errors) -{ - struct acm_ste_policy_buffer *ste_buf = - (struct acm_ste_policy_buffer *)buf; - - if ( buf_size < sizeof(struct acm_ste_policy_buffer) ) - return -EINVAL; - - /* Convert endianess of policy */ - ste_buf->policy_code = be32_to_cpu(ste_buf->policy_code); - ste_buf->policy_version = be32_to_cpu(ste_buf->policy_version); - ste_buf->ste_max_types = be32_to_cpu(ste_buf->ste_max_types); - ste_buf->ste_max_ssidrefs = be32_to_cpu(ste_buf->ste_max_ssidrefs); - ste_buf->ste_ssid_offset = be32_to_cpu(ste_buf->ste_ssid_offset); - - /* policy type and version checks */ - if ( (ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) || - (ste_buf->policy_version != ACM_STE_VERSION) ) - return -EINVAL; - - /* during boot dom0_chwall_ssidref is set */ - if ( is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs) ) - return -EINVAL; - - return _ste_update_policy(buf, buf_size, 1, errors); -} - -static int -ste_set_policy(u8 *buf, u32 buf_size) -{ - return _ste_update_policy(buf, buf_size, 0, NULL); -} - -static int -ste_dump_stats(u8 *buf, u16 buf_len) -{ - struct acm_ste_stats_buffer stats; - - /* now send the hook counts to user space */ - stats.ec_eval_count = - cpu_to_be32(atomic_read(&ste_bin_pol.ec_eval_count)); - stats.gt_eval_count = - cpu_to_be32(atomic_read(&ste_bin_pol.gt_eval_count)); - stats.ec_denied_count = - cpu_to_be32(atomic_read(&ste_bin_pol.ec_denied_count)); - stats.gt_denied_count = - cpu_to_be32(atomic_read(&ste_bin_pol.gt_denied_count)); - stats.ec_cachehit_count = - cpu_to_be32(atomic_read(&ste_bin_pol.ec_cachehit_count)); - stats.gt_cachehit_count = - cpu_to_be32(atomic_read(&ste_bin_pol.gt_cachehit_count)); - - if ( buf_len < sizeof(struct acm_ste_stats_buffer) ) - return -ENOMEM; - - memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer)); - - return sizeof(struct acm_ste_stats_buffer); -} - -static int -ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) -{ - int i; - - /* fill in buffer */ - if ( ste_bin_pol.max_types > len ) - return -EFAULT; - - if ( ssidref >= ste_bin_pol.max_ssidrefs ) - return -EFAULT; - - /* read types for chwall ssidref */ - for( i = 0; i< ste_bin_pol.max_types; i++ ) - { - if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) - buf[i] = 1; - else - buf[i] = 0; - } - return ste_bin_pol.max_types; -} - -/* we need to go through this before calling the hooks, - * returns 1 == cache hit */ -static int inline -check_cache(struct domain *dom, domid_t rdom) -{ - struct ste_ssid *ste_ssid; - int i; - - printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); - - if (dom->ssid == NULL) - return 0; - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(dom->ssid)); - - for( i = 0; i < ACM_TE_CACHE_SIZE; i++ ) - { - if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) && - (ste_ssid->ste_cache[i].id == rdom) ) - { - printkd("cache hit (entry %x, id= %x!\n", - i, - ste_ssid->ste_cache[i].id); - return 1; - } - } - return 0; -} - - -/* we only get here if there is NO entry yet; no duplication check! */ -static void inline -cache_result(struct domain *subj, struct domain *obj) { - struct ste_ssid *ste_ssid; - int i; - - printkd("caching from doms: %x --> %x.\n", - subj->domain_id, obj->domain_id); - - if ( subj->ssid == NULL ) - return; - - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(subj)->ssid); - - for( i = 0; i < ACM_TE_CACHE_SIZE; i++ ) - if ( ste_ssid->ste_cache[i].valid == ACM_STE_free ) - break; - if ( i < ACM_TE_CACHE_SIZE ) - { - ste_ssid->ste_cache[i].valid = ACM_STE_valid; - ste_ssid->ste_cache[i].id = obj->domain_id; - } else - printk ("Cache of dom %x is full!\n", subj->domain_id); -} - -/* deletes entries for domain 'id' from all caches (re-use) */ -static void inline -clean_id_from_cache(domid_t id) -{ - struct ste_ssid *ste_ssid; - int i; - struct acm_ssid_domain *rawssid; - - printkd("deleting cache for dom %x.\n", id); - - read_lock(&ssid_list_rwlock); - /* look through caches of all domains */ - - for_each_acmssid ( rawssid ) - { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid); - - if ( !ste_ssid ) - { - printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n", - __func__); - goto out; - } - for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ ) - if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) && - (ste_ssid->ste_cache[i].id == id) ) - ste_ssid->ste_cache[i].valid = ACM_STE_free; - } - - out: - read_unlock(&ssid_list_rwlock); -} - -/*************************** - * Authorization functions - **************************/ -static int -ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref) -{ - /* check for ssidref in range for policy */ - ssidref_t ste_ssidref; - - traceprintk("%s.\n", __func__); - - read_lock(&acm_bin_pol_rwlock); - - ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); - - if ( ste_ssidref >= ste_bin_pol.max_ssidrefs ) - { - printk("%s: ERROR ste_ssidref > max(%x).\n", - __func__, ste_bin_pol.max_ssidrefs-1); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; - } - - read_unlock(&acm_bin_pol_rwlock); - - return ACM_ACCESS_PERMITTED; -} - -static int -ste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t domid) -{ - return ste_pre_domain_create(subject_ssid, ssidref); -} - - -static void -ste_domain_destroy(void *subject_ssid, struct domain *d) -{ - /* clean all cache entries for destroyed domain (might be re-used) */ - clean_id_from_cache(d->domain_id); -} - -/* -------- EVENTCHANNEL OPERATIONS -----------*/ -static int -ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - (id1 == DOMID_SELF) ? current->domain->domain_id : id1, - (id2 == DOMID_SELF) ? current->domain->domain_id : id2); - - if ( id1 == DOMID_SELF ) - id1 = current->domain->domain_id; - if ( id2 == DOMID_SELF ) - id2 = current->domain->domain_id; - - subj = rcu_lock_domain_by_id(id1); - obj = rcu_lock_domain_by_id(id2); - if ( (subj == NULL) || (obj == NULL) ) - { - ret = ACM_ACCESS_DENIED; - goto out; - } - /* cache check late */ - if ( check_cache(subj, obj->domain_id) ) - { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - ret = ACM_ACCESS_PERMITTED; - goto out; - } - atomic_inc(&ste_bin_pol.ec_eval_count); - - if ( share_common_type(subj, obj) ) - { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } - else - { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } - - out: - if ( obj != NULL ) - rcu_unlock_domain(obj); - if ( subj != NULL ) - rcu_unlock_domain(subj); - return ret; -} - -static int -ste_pre_eventchannel_interdomain(domid_t id) -{ - struct domain *subj=NULL, *obj=NULL; - int ret; - - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, - (id == DOMID_SELF) ? current->domain->domain_id : id); - - /* following is a bit longer but ensures that we - * "put" only domains that we where "find"-ing - */ - if ( id == DOMID_SELF ) - id = current->domain->domain_id; - - subj = current->domain; - obj = rcu_lock_domain_by_id(id); - if ( obj == NULL ) - { - ret = ACM_ACCESS_DENIED; - goto out; - } - - /* cache check late, but evtchn is not on performance critical path */ - if ( check_cache(subj, obj->domain_id) ) - { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - ret = ACM_ACCESS_PERMITTED; - goto out; - } - - atomic_inc(&ste_bin_pol.ec_eval_count); - - if ( share_common_type(subj, obj) ) - { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } - else - { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } - - out: - if ( obj != NULL ) - rcu_unlock_domain(obj); - return ret; -} - -/* -------- SHARED MEMORY OPERATIONS -----------*/ - -static int -ste_pre_grant_map_ref (domid_t id) -{ - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); - - if ( check_cache(current->domain, id) ) - { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - subj = current->domain; - obj = rcu_lock_domain_by_id(id); - - if ( share_common_type(subj, obj) ) - { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } - else - { - atomic_inc(&ste_bin_pol.gt_denied_count); - printkd("%s: ACCESS DENIED!\n", __func__); - ret = ACM_ACCESS_DENIED; - } - if ( obj != NULL ) - rcu_unlock_domain(obj); - return ret; -} - - -/* since setting up grant tables involves some implicit information - flow from the creating domain to the domain that is setup, we - check types in addition to the general authorization */ -static int -ste_pre_grant_setup (domid_t id) -{ - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); - - if ( check_cache(current->domain, id) ) - { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - subj = current->domain; - obj = rcu_lock_domain_by_id(id); - - /* a) check authorization (eventually use specific capabilities) */ - if ( obj && !IS_PRIV_FOR(current->domain, obj) ) - { - printk("%s: Grant table management authorization denied ERROR!\n", - __func__); - rcu_unlock_domain(obj); - return ACM_ACCESS_DENIED; - } - - /* b) check types */ - if ( share_common_type(subj, obj) ) - { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } - else - { - atomic_inc(&ste_bin_pol.gt_denied_count); - ret = ACM_ACCESS_DENIED; - } - if ( obj != NULL ) - rcu_unlock_domain(obj); - return ret; -} - -/* -------- DOMAIN-Requested Decision hooks -----------*/ - -static int -ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2) -{ - int hct = have_common_type( - GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1), - GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2)); - return (hct ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED); -} - -static int -ste_authorization(ssidref_t ssidref1, ssidref_t ssidref2) -{ - int iss = is_superset( - GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1), - GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2)); - return (iss ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED); -} - -static int -ste_is_default_policy(void) -{ - const static domaintype_t def_policy[4] = { 0x0, 0x1, 0x1, 0x1}; - return ((ste_bin_pol.max_types == 2) && - (ste_bin_pol.max_ssidrefs == 2) && - (memcmp(ste_bin_pol.ssidrefs, - def_policy, - sizeof(def_policy)) == 0)); -} - -/* now define the hook structure similarly to LSM */ -struct acm_operations acm_simple_type_enforcement_ops = { - - /* policy management services */ - .init_domain_ssid = ste_init_domain_ssid, - .free_domain_ssid = ste_free_domain_ssid, - .dump_binary_policy = ste_dump_policy, - .test_binary_policy = ste_test_policy, - .set_binary_policy = ste_set_policy, - .dump_statistics = ste_dump_stats, - .dump_ssid_types = ste_dump_ssid_types, - - /* domain management control hooks */ - .domain_create = ste_domain_create, - .domain_destroy = ste_domain_destroy, - - /* event channel control hooks */ - .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, - .fail_eventchannel_interdomain = NULL, - - /* grant table control hooks */ - .pre_grant_map_ref = ste_pre_grant_map_ref, - .fail_grant_map_ref = NULL, - .pre_grant_setup = ste_pre_grant_setup, - .fail_grant_setup = NULL, - /* generic domain-requested decision hooks */ - .sharing = ste_sharing, - .authorization = ste_authorization, - .conflictset = NULL, - - .is_default_policy = ste_is_default_policy, -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/xsm/acm/acm_xsm_hooks.c b/xen/xsm/acm/acm_xsm_hooks.c deleted file mode 100644 index 6d3202b45f..0000000000 --- a/xen/xsm/acm/acm_xsm_hooks.c +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************** - * acm_xsm_hooks.c - * - * Copyright (C) 2005 IBM Corporation - * - * Author: - * Reiner Sailer <sailer@watson.ibm.com> - * - * Contributors: - * Michael LeMay, <mdlemay@epoch.ncsc.mil> - * George Coker, <gscoker@alpha.ncsc.mil> - * - * sHype hooks for XSM based on the original ACM hooks. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - */ - -#include <xsm/xsm.h> -#include <xsm/acm/acm_hooks.h> -#include <public/xsm/acm.h> - -static int acm_grant_mapref( - struct domain *ld, struct domain *rd, uint32_t flags) -{ - domid_t id = rd->domain_id; - - return acm_pre_grant_map_ref(id); -} - -static int acm_evtchn_unbound( - struct domain *d1, struct evtchn *chn1, domid_t id2) -{ - domid_t id1 = d1->domain_id; - - return acm_pre_eventchannel_unbound(id1, id2); -} - -static int acm_evtchn_interdomain( - struct domain *d1, struct evtchn *chn1, - struct domain *d2, struct evtchn *chn2) -{ - domid_t id2 = d2->domain_id; - - return acm_pre_eventchannel_interdomain(id2); -} - -static void acm_security_domaininfo( - struct domain *d, struct xen_domctl_getdomaininfo *info) -{ - if ( d->ssid != NULL ) - info->ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref; - else - info->ssidref = ACM_DEFAULT_SSID; -} - -extern long do_acm_op(XEN_GUEST_HANDLE(xsm_op_t) arg); - -struct xsm_operations acm_xsm_ops = { - .domain_create = acm_domain_create, - .free_security_domain = acm_domain_destroy, - - .grant_mapref = acm_grant_mapref, - - .evtchn_unbound = acm_evtchn_unbound, - .evtchn_interdomain = acm_evtchn_interdomain, - - .security_domaininfo = acm_security_domaininfo, - - .__do_xsm_op = do_acm_op, -}; diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c index dcab94d580..c5b334e7e9 100644 --- a/xen/xsm/xsm_policy.c +++ b/xen/xsm/xsm_policy.c @@ -15,7 +15,6 @@ * * * This file contains the XSM policy init functions for Xen. - * This file is based on the ACM functions of the same name. * */ |