ia64/xen-unstable

view xen/acm/acm_core.c @ 9706:3c05406f5e0a

In some cases, say for instance for some bizzare reason
the tree was checked out of CVS, which doens't neccessarily
store file permissions, mkbuildtree may not be executable.
So run them explicitly via bash.

Signed-Off-By: Horms <horms@verge.net.au>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 13 11:24:00 2006 +0100 (2006-04-13)
parents cc1d77bba4b0
children 0a5183b3e7bb
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 * Contributors:
10 * Stefan Berger <stefanb@watson.ibm.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation, version 2 of the
15 * License.
16 *
17 * sHype access control module (ACM)
18 * This file handles initialization of the ACM
19 * as well as initializing/freeing security
20 * identifiers for domains (it calls on active
21 * policy hook functions).
22 *
23 */
25 #include <xen/config.h>
26 #include <xen/errno.h>
27 #include <xen/types.h>
28 #include <xen/lib.h>
29 #include <xen/delay.h>
30 #include <xen/sched.h>
31 #include <xen/multiboot.h>
32 #include <acm/acm_hooks.h>
33 #include <acm/acm_endian.h>
35 /* debug:
36 * include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
37 * define/undefine this constant to receive / suppress any
38 * security hook debug output of sHype
39 *
40 * include/public/acm.h defines a constant ACM_DEBUG
41 * define/undefine this constant to receive non-hook-related
42 * debug output.
43 */
45 /* function prototypes */
46 void acm_init_chwall_policy(void);
47 void acm_init_ste_policy(void);
49 extern struct acm_operations acm_chinesewall_ops,
50 acm_simple_type_enforcement_ops, acm_null_ops;
52 /* global ACM policy (now dynamically determined at boot time) */
53 u16 acm_active_security_policy = ACM_POLICY_UNDEFINED;
55 /* global ops structs called by the hooks */
56 struct acm_operations *acm_primary_ops = NULL;
57 /* called in hook if-and-only-if primary succeeds */
58 struct acm_operations *acm_secondary_ops = NULL;
60 /* acm global binary policy (points to 'local' primary and secondary policies */
61 struct acm_binary_policy acm_bin_pol;
62 /* acm binary policy lock */
63 rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
65 /* until we have endian support in Xen, we discover it at runtime */
66 u8 little_endian = 1;
67 void
68 acm_set_endian(void)
69 {
70 u32 test = 1;
71 if (*((u8 *)&test) == 1)
72 {
73 printk("ACM module running in LITTLE ENDIAN.\n");
74 little_endian = 1;
75 }
76 else
77 {
78 printk("ACM module running in BIG ENDIAN.\n");
79 little_endian = 0;
80 }
81 }
83 int
84 acm_init_binary_policy(u32 policy_code)
85 {
86 int ret = ACM_OK;
88 acm_bin_pol.primary_policy_code = (policy_code & 0x0f);
89 acm_bin_pol.secondary_policy_code = (policy_code >> 4) & 0x0f;
91 write_lock(&acm_bin_pol_rwlock);
93 /* set primary policy component */
94 switch ((policy_code) & 0x0f)
95 {
97 case ACM_CHINESE_WALL_POLICY:
98 acm_init_chwall_policy();
99 acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
100 acm_primary_ops = &acm_chinesewall_ops;
101 break;
103 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
104 acm_init_ste_policy();
105 acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
106 acm_primary_ops = &acm_simple_type_enforcement_ops;
107 break;
109 case ACM_NULL_POLICY:
110 acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
111 acm_primary_ops = &acm_null_ops;
112 break;
114 default:
115 /* Unknown policy not allowed primary */
116 ret = -EINVAL;
117 goto out;
118 }
120 /* secondary policy component part */
121 switch ((policy_code) >> 4)
122 {
124 case ACM_NULL_POLICY:
125 acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
126 acm_secondary_ops = &acm_null_ops;
127 break;
129 case ACM_CHINESE_WALL_POLICY:
130 if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
131 { /* not a valid combination */
132 ret = -EINVAL;
133 goto out;
134 }
135 acm_init_chwall_policy();
136 acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
137 acm_secondary_ops = &acm_chinesewall_ops;
138 break;
140 case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
141 if (acm_bin_pol.primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
142 { /* not a valid combination */
143 ret = -EINVAL;
144 goto out;
145 }
146 acm_init_ste_policy();
147 acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
148 acm_secondary_ops = &acm_simple_type_enforcement_ops;
149 break;
151 default:
152 ret = -EINVAL;
153 goto out;
154 }
156 out:
157 write_unlock(&acm_bin_pol_rwlock);
158 return ret;
159 }
161 static int
162 acm_setup(unsigned int *initrdidx,
163 const multiboot_info_t *mbi,
164 unsigned long initial_images_start)
165 {
166 int i;
167 module_t *mod = (module_t *)__va(mbi->mods_addr);
168 int rc = ACM_OK;
170 if (mbi->mods_count > 1)
171 *initrdidx = 1;
173 /*
174 * Try all modules and see whichever could be the binary policy.
175 * Adjust the initrdidx if module[1] is the binary policy.
176 */
177 for (i = mbi->mods_count-1; i >= 1; i--)
178 {
179 struct acm_policy_buffer *pol;
180 char *_policy_start;
181 unsigned long _policy_len;
182 #if defined(__i386__)
183 _policy_start = (char *)(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
184 #elif defined(__x86_64__)
185 _policy_start = __va(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
186 #else
187 #error Architecture unsupported by sHype
188 #endif
189 _policy_len = mod[i].mod_end - mod[i].mod_start;
190 if (_policy_len < sizeof(struct acm_policy_buffer))
191 continue; /* not a policy */
193 pol = (struct acm_policy_buffer *)_policy_start;
194 if (ntohl(pol->magic) == ACM_MAGIC)
195 {
196 rc = acm_set_policy((void *)_policy_start,
197 (u32)_policy_len,
198 0);
199 if (rc == ACM_OK)
200 {
201 printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start);
202 if (i == 1)
203 {
204 if (mbi->mods_count > 2)
205 {
206 *initrdidx = 2;
207 }
208 else {
209 *initrdidx = 0;
210 }
211 }
212 else
213 {
214 *initrdidx = 1;
215 }
216 break;
217 }
218 else
219 {
220 printk("Invalid policy. %d.th module line.\n", i+1);
221 }
222 } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */
223 }
224 return rc;
225 }
228 int
229 acm_init(unsigned int *initrdidx,
230 const multiboot_info_t *mbi,
231 unsigned long initial_images_start)
232 {
233 int ret = ACM_OK;
235 acm_set_endian();
237 /* first try to load the boot policy (uses its own locks) */
238 acm_setup(initrdidx, mbi, initial_images_start);
240 if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
241 {
242 printk("%s: Boot-Policy. Enforcing %s: Primary %s, Secondary %s.\n", __func__,
243 ACM_POLICY_NAME(acm_active_security_policy),
244 ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
245 ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
246 goto out;
247 }
248 /* else continue with the minimal hardcoded default startup policy */
249 printk("%s: Loading default policy (%s).\n",
250 __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
252 if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
253 ret = -EINVAL;
254 goto out;
255 }
256 acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY;
258 out:
259 if (ret != ACM_OK)
260 {
261 printk("%s: Error initializing policies.\n", __func__);
262 /* here one could imagine a clean panic */
263 return -EINVAL;
264 }
265 return ret;
266 }
268 int
269 acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
270 {
271 struct acm_ssid_domain *ssid;
272 struct domain *subj = find_domain_by_id(id);
273 int ret1, ret2;
275 if (subj == NULL)
276 {
277 printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
278 return ACM_NULL_POINTER_ERROR;
279 }
280 if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
281 {
282 put_domain(subj);
283 return ACM_INIT_SSID_ERROR;
284 }
286 ssid->datatype = DOMAIN;
287 ssid->subject = subj;
288 ssid->domainid = subj->domain_id;
289 ssid->primary_ssid = NULL;
290 ssid->secondary_ssid = NULL;
292 if (acm_active_security_policy != ACM_NULL_POLICY)
293 ssid->ssidref = ssidref;
294 else
295 ssid->ssidref = ACM_DEFAULT_SSID;
297 subj->ssid = ssid;
298 /* now fill in primary and secondary parts; we only get here through hooks */
299 if (acm_primary_ops->init_domain_ssid != NULL)
300 ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
301 else
302 ret1 = ACM_OK;
304 if (acm_secondary_ops->init_domain_ssid != NULL)
305 ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
306 else
307 ret2 = ACM_OK;
309 if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
310 {
311 printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
312 __func__, subj->domain_id);
313 acm_free_domain_ssid(ssid);
314 put_domain(subj);
315 return ACM_INIT_SSID_ERROR;
316 }
317 printk("%s: assigned domain %x the ssidref=%x.\n",
318 __func__, id, ssid->ssidref);
319 put_domain(subj);
320 return ACM_OK;
321 }
324 void
325 acm_free_domain_ssid(struct acm_ssid_domain *ssid)
326 {
327 /* domain is already gone, just ssid is left */
328 if (ssid == NULL)
329 return;
331 ssid->subject = NULL;
332 if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
333 acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
334 ssid->primary_ssid = NULL;
335 if (acm_secondary_ops->free_domain_ssid != NULL)
336 acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
337 ssid->secondary_ssid = NULL;
338 xfree(ssid);
339 printkd("%s: Freed individual domain ssid (domain=%02x).\n",
340 __func__, id);
341 }
343 /*
344 * Local variables:
345 * mode: C
346 * c-set-style: "BSD"
347 * c-basic-offset: 4
348 * tab-width: 4
349 * indent-tabs-mode: nil
350 * End:
351 */