direct-io.hg

view xen/acm/acm_core.c @ 5517:10e9028c8e3d

bitkeeper revision 1.1718.1.10 (42b7b19aqOS_1M8I4pIOFjiTPYWV-g)

Merge bk://xenbits.xensource.com/xen-unstable.bk
into spot.cl.cam.ac.uk:C:/Documents and Settings/iap10/xen-unstable.bk
author iap10@spot.cl.cam.ac.uk
date Tue Jun 21 06:20:10 2005 +0000 (2005-06-21)
parents aa52b853c28b
children 649cd37aa1ab
line source
1 /****************************************************************
2 * acm_core.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Author:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 *
14 * sHype access control module (ACM)
15 * This file handles initialization of the ACM
16 * as well as initializing/freeing security
17 * identifiers for domains (it calls on active
18 * policy hook functions).
19 *
20 */
22 #include <xen/config.h>
23 #include <xen/errno.h>
24 #include <xen/types.h>
25 #include <xen/lib.h>
26 #include <xen/delay.h>
27 #include <xen/sched.h>
28 #include <acm/acm_hooks.h>
29 #include <acm/acm_endian.h>
31 /* debug:
32 * include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
33 * define/undefine this constant to receive / suppress any
34 * security hook debug output of sHype
35 *
36 * include/public/acm.h defines a constant ACM_DEBUG
37 * define/undefine this constant to receive non-hook-related
38 * debug output.
39 */
41 /* function prototypes */
42 void acm_init_chwall_policy(void);
43 void acm_init_ste_policy(void);
45 extern struct acm_operations acm_chinesewall_ops,
46 acm_simple_type_enforcement_ops, acm_null_ops;
48 /* global ops structs called by the hooks */
49 struct acm_operations *acm_primary_ops = NULL;
50 /* called in hook if-and-only-if primary succeeds */
51 struct acm_operations *acm_secondary_ops = NULL;
53 /* acm global binary policy (points to 'local' primary and secondary policies */
54 struct acm_binary_policy acm_bin_pol;
55 /* acm binary policy lock */
56 rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
58 /* until we have endian support in Xen, we discover it at runtime */
59 u8 little_endian = 1;
60 void acm_set_endian(void)
61 {
62 u32 test = 1;
63 if (*((u8 *)&test) == 1) {
64 printk("ACM module running in LITTLE ENDIAN.\n");
65 little_endian = 1;
66 } else {
67 printk("ACM module running in BIG ENDIAN.\n");
68 little_endian = 0;
69 }
70 }
72 /* initialize global security policy for Xen; policy write-locked already */
73 static void
74 acm_init_binary_policy(void *primary, void *secondary)
75 {
76 acm_bin_pol.primary_policy_code = 0;
77 acm_bin_pol.secondary_policy_code = 0;
78 acm_bin_pol.primary_binary_policy = primary;
79 acm_bin_pol.secondary_binary_policy = secondary;
80 }
82 int
83 acm_init(void)
84 {
85 int ret = -EINVAL;
87 acm_set_endian();
88 write_lock(&acm_bin_pol_rwlock);
90 if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
91 acm_init_binary_policy(NULL, NULL);
92 acm_init_chwall_policy();
93 acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
94 acm_primary_ops = &acm_chinesewall_ops;
95 acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
96 acm_secondary_ops = &acm_null_ops;
97 ret = ACM_OK;
98 } else if (ACM_USE_SECURITY_POLICY == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
99 acm_init_binary_policy(NULL, NULL);
100 acm_init_ste_policy();
101 acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
102 acm_primary_ops = &acm_simple_type_enforcement_ops;
103 acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
104 acm_secondary_ops = &acm_null_ops;
105 ret = ACM_OK;
106 } else if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
107 acm_init_binary_policy(NULL, NULL);
108 acm_init_chwall_policy();
109 acm_init_ste_policy();
110 acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
111 acm_primary_ops = &acm_chinesewall_ops;
112 acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
113 acm_secondary_ops = &acm_simple_type_enforcement_ops;
114 ret = ACM_OK;
115 } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
116 acm_init_binary_policy(NULL, NULL);
117 acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
118 acm_primary_ops = &acm_null_ops;
119 acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
120 acm_secondary_ops = &acm_null_ops;
121 ret = ACM_OK;
122 }
123 write_unlock(&acm_bin_pol_rwlock);
125 if (ret != ACM_OK)
126 return -EINVAL;
127 printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__,
128 ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
129 return ACM_OK;
130 }
133 int
134 acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
135 {
136 struct acm_ssid_domain *ssid;
137 struct domain *subj = find_domain_by_id(id);
138 int ret1, ret2;
140 if (subj == NULL) {
141 printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
142 return ACM_NULL_POINTER_ERROR;
143 }
144 if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
145 return ACM_INIT_SSID_ERROR;
147 ssid->datatype = DOMAIN;
148 ssid->subject = subj;
149 ssid->domainid = subj->domain_id;
150 ssid->primary_ssid = NULL;
151 ssid->secondary_ssid = NULL;
153 if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
154 ssid->ssidref = ssidref;
155 else
156 ssid->ssidref = ACM_DEFAULT_SSID;
158 subj->ssid = ssid;
159 /* now fill in primary and secondary parts; we only get here through hooks */
160 if (acm_primary_ops->init_domain_ssid != NULL)
161 ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
162 else
163 ret1 = ACM_OK;
165 if (acm_secondary_ops->init_domain_ssid != NULL)
166 ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
167 else
168 ret2 = ACM_OK;
170 if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
171 printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
172 __func__, subj->domain_id);
173 acm_free_domain_ssid(ssid);
174 put_domain(subj);
175 return ACM_INIT_SSID_ERROR;
176 }
177 printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref);
178 put_domain(subj);
179 return ACM_OK;
180 }
183 int
184 acm_free_domain_ssid(struct acm_ssid_domain *ssid)
185 {
186 domid_t id;
188 /* domain is already gone, just ssid is left */
189 if (ssid == NULL) {
190 printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
191 return ACM_NULL_POINTER_ERROR;
192 }
193 id = ssid->domainid;
194 ssid->subject = NULL;
196 if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
197 acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
198 ssid->primary_ssid = NULL;
199 if (acm_secondary_ops->free_domain_ssid != NULL)
200 acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
201 ssid->secondary_ssid = NULL;
202 xfree(ssid);
203 printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, id);
204 return ACM_OK;
205 }