ia64/xen-unstable

view xen/acm/acm_chinesewall_hooks.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 fcb7e5616102
children d088aec406c0
line source
1 /****************************************************************
2 * acm_chinesewall_hooks.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Author:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 *
9 * Contributions:
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 Chinese Wall Policy for Xen
18 * This code implements the hooks that are called
19 * throughout Xen operations and decides authorization
20 * based on domain types and Chinese Wall conflict type
21 * sets. The CHWALL policy decides if a new domain can be started
22 * based on the types of running domains and the type of the
23 * new domain to be started. If the new domain's type is in
24 * conflict with types of running domains, then this new domain
25 * is not allowed to be created. A domain can have multiple types,
26 * in which case all types of a new domain must be conflict-free
27 * with all types of already running domains.
28 *
29 * indent -i4 -kr -nut
30 *
31 */
33 #include <xen/config.h>
34 #include <xen/errno.h>
35 #include <xen/types.h>
36 #include <xen/lib.h>
37 #include <xen/delay.h>
38 #include <xen/sched.h>
39 #include <public/acm.h>
40 #include <asm/atomic.h>
41 #include <acm/acm_core.h>
42 #include <acm/acm_hooks.h>
43 #include <acm/acm_endian.h>
45 /* local cache structures for chinese wall policy */
46 struct chwall_binary_policy chwall_bin_pol;
48 /*
49 * Initializing chinese wall policy (will be filled by policy partition
50 * using setpolicy command)
51 */
52 int acm_init_chwall_policy(void)
53 {
54 /* minimal startup policy; policy write-locked already */
55 chwall_bin_pol.max_types = 1;
56 chwall_bin_pol.max_ssidrefs = 2;
57 chwall_bin_pol.max_conflictsets = 1;
58 chwall_bin_pol.ssidrefs =
59 (domaintype_t *) xmalloc_array(domaintype_t,
60 chwall_bin_pol.max_ssidrefs *
61 chwall_bin_pol.max_types);
62 chwall_bin_pol.conflict_sets =
63 (domaintype_t *) xmalloc_array(domaintype_t,
64 chwall_bin_pol.max_conflictsets *
65 chwall_bin_pol.max_types);
66 chwall_bin_pol.running_types =
67 (domaintype_t *) xmalloc_array(domaintype_t,
68 chwall_bin_pol.max_types);
69 chwall_bin_pol.conflict_aggregate_set =
70 (domaintype_t *) xmalloc_array(domaintype_t,
71 chwall_bin_pol.max_types);
73 if ((chwall_bin_pol.conflict_sets == NULL)
74 || (chwall_bin_pol.running_types == NULL)
75 || (chwall_bin_pol.ssidrefs == NULL)
76 || (chwall_bin_pol.conflict_aggregate_set == NULL))
77 return ACM_INIT_SSID_ERROR;
79 /* initialize state */
80 memset((void *) chwall_bin_pol.ssidrefs, 0,
81 chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types *
82 sizeof(domaintype_t));
83 memset((void *) chwall_bin_pol.conflict_sets, 0,
84 chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types *
85 sizeof(domaintype_t));
86 memset((void *) chwall_bin_pol.running_types, 0,
87 chwall_bin_pol.max_types * sizeof(domaintype_t));
88 memset((void *) chwall_bin_pol.conflict_aggregate_set, 0,
89 chwall_bin_pol.max_types * sizeof(domaintype_t));
90 return ACM_OK;
91 }
93 static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
94 {
95 struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
96 traceprintk("%s.\n", __func__);
97 if (chwall_ssidp == NULL)
98 return ACM_INIT_SSID_ERROR;
100 chwall_ssidp->chwall_ssidref =
101 GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
103 if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
104 || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID))
105 {
106 printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n",
107 __func__, chwall_ssidp->chwall_ssidref);
108 xfree(chwall_ssidp);
109 return ACM_INIT_SSID_ERROR;
110 }
111 (*chwall_ssid) = chwall_ssidp;
112 printkd("%s: determined chwall_ssidref to %x.\n",
113 __func__, chwall_ssidp->chwall_ssidref);
114 return ACM_OK;
115 }
117 static void chwall_free_domain_ssid(void *chwall_ssid)
118 {
119 traceprintk("%s.\n", __func__);
120 xfree(chwall_ssid);
121 return;
122 }
125 /* dump chinese wall cache; policy read-locked already */
126 static int chwall_dump_policy(u8 * buf, u32 buf_size)
127 {
128 struct acm_chwall_policy_buffer *chwall_buf =
129 (struct acm_chwall_policy_buffer *) buf;
130 int ret = 0;
132 if (buf_size < sizeof(struct acm_chwall_policy_buffer))
133 return -EINVAL;
135 chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types);
136 chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs);
137 chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
138 chwall_buf->chwall_ssid_offset =
139 htonl(sizeof(struct acm_chwall_policy_buffer));
140 chwall_buf->chwall_max_conflictsets =
141 htonl(chwall_bin_pol.max_conflictsets);
142 chwall_buf->chwall_conflict_sets_offset =
143 htonl(ntohl(chwall_buf->chwall_ssid_offset) +
144 sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs *
145 chwall_bin_pol.max_types);
146 chwall_buf->chwall_running_types_offset =
147 htonl(ntohl(chwall_buf->chwall_conflict_sets_offset) +
148 sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
149 chwall_bin_pol.max_types);
150 chwall_buf->chwall_conflict_aggregate_offset =
151 htonl(ntohl(chwall_buf->chwall_running_types_offset) +
152 sizeof(domaintype_t) * chwall_bin_pol.max_types);
154 ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) +
155 sizeof(domaintype_t) * chwall_bin_pol.max_types;
157 if (buf_size < ret)
158 return -EINVAL;
160 /* now copy buffers over */
161 arrcpy16((u16 *) (buf + ntohl(chwall_buf->chwall_ssid_offset)),
162 chwall_bin_pol.ssidrefs,
163 chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
165 arrcpy16((u16 *) (buf +
166 ntohl(chwall_buf->chwall_conflict_sets_offset)),
167 chwall_bin_pol.conflict_sets,
168 chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
170 arrcpy16((u16 *) (buf +
171 ntohl(chwall_buf->chwall_running_types_offset)),
172 chwall_bin_pol.running_types, chwall_bin_pol.max_types);
174 arrcpy16((u16 *) (buf +
175 ntohl(chwall_buf->chwall_conflict_aggregate_offset)),
176 chwall_bin_pol.conflict_aggregate_set,
177 chwall_bin_pol.max_types);
178 return ret;
179 }
181 /* adapt security state (running_types and conflict_aggregate_set) to all running
182 * domains; chwall_init_state is called when a policy is changed to bring the security
183 * information into a consistent state and to detect violations (return != 0).
184 * from a security point of view, we simulate that all running domains are re-started
185 */
186 static int
187 chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
188 domaintype_t * ssidrefs, domaintype_t * conflict_sets,
189 domaintype_t * running_types,
190 domaintype_t * conflict_aggregate_set)
191 {
192 int violation = 0, i, j;
193 struct chwall_ssid *chwall_ssid;
194 ssidref_t chwall_ssidref;
195 struct domain **pd;
197 write_lock(&domlist_lock);
198 /* go through all domains and adjust policy as if this domain was started now */
199 pd = &domain_list;
200 for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list)
201 {
202 chwall_ssid =
203 GET_SSIDP(ACM_CHINESE_WALL_POLICY,
204 (struct acm_ssid_domain *) (*pd)->ssid);
205 chwall_ssidref = chwall_ssid->chwall_ssidref;
206 traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
207 __func__, (*pd)->domain_id, chwall_ssidref);
208 /* a) adjust types ref-count for running domains */
209 for (i = 0; i < chwall_buf->chwall_max_types; i++)
210 running_types[i] +=
211 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i];
213 /* b) check for conflict */
214 for (i = 0; i < chwall_buf->chwall_max_types; i++)
215 if (conflict_aggregate_set[i] &&
216 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i])
217 {
218 printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
219 __func__, i);
220 violation = 1;
221 goto out;
222 }
223 /* set violation and break out of the loop */
224 /* c) adapt conflict aggregate set for this domain (notice conflicts) */
225 for (i = 0; i < chwall_buf->chwall_max_conflictsets; i++)
226 {
227 int common = 0;
228 /* check if conflict_set_i and ssidref have common types */
229 for (j = 0; j < chwall_buf->chwall_max_types; j++)
230 if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
231 ssidrefs[chwall_ssidref *
232 chwall_buf->chwall_max_types + j])
233 {
234 common = 1;
235 break;
236 }
237 if (common == 0)
238 continue; /* try next conflict set */
239 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
240 for (j = 0; j < chwall_buf->chwall_max_types; j++)
241 if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
242 !ssidrefs[chwall_ssidref *
243 chwall_buf->chwall_max_types + j])
244 conflict_aggregate_set[j]++;
245 }
246 }
247 out:
248 write_unlock(&domlist_lock);
249 return violation;
250 /* returning "violation != 0" means that the currently running set of domains would
251 * not be possible if the new policy had been enforced before starting them; for chinese
252 * wall, this means that the new policy includes at least one conflict set of which
253 * more than one type is currently running */
254 }
256 static int chwall_set_policy(u8 * buf, u32 buf_size)
257 {
258 /* policy write-locked already */
259 struct acm_chwall_policy_buffer *chwall_buf =
260 (struct acm_chwall_policy_buffer *) buf;
261 void *ssids = NULL, *conflict_sets = NULL, *running_types =
262 NULL, *conflict_aggregate_set = NULL;
264 if (buf_size < sizeof(struct acm_chwall_policy_buffer))
265 return -EINVAL;
267 /* rewrite the policy due to endianess */
268 chwall_buf->policy_code = ntohl(chwall_buf->policy_code);
269 chwall_buf->policy_version = ntohl(chwall_buf->policy_version);
270 chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types);
271 chwall_buf->chwall_max_ssidrefs =
272 ntohl(chwall_buf->chwall_max_ssidrefs);
273 chwall_buf->chwall_max_conflictsets =
274 ntohl(chwall_buf->chwall_max_conflictsets);
275 chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset);
276 chwall_buf->chwall_conflict_sets_offset =
277 ntohl(chwall_buf->chwall_conflict_sets_offset);
278 chwall_buf->chwall_running_types_offset =
279 ntohl(chwall_buf->chwall_running_types_offset);
280 chwall_buf->chwall_conflict_aggregate_offset =
281 ntohl(chwall_buf->chwall_conflict_aggregate_offset);
283 /* policy type and version checks */
284 if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
285 (chwall_buf->policy_version != ACM_CHWALL_VERSION))
286 return -EINVAL;
288 /* 1. allocate new buffers */
289 ssids =
290 xmalloc_array(domaintype_t,
291 chwall_buf->chwall_max_types *
292 chwall_buf->chwall_max_ssidrefs);
293 conflict_sets =
294 xmalloc_array(domaintype_t,
295 chwall_buf->chwall_max_conflictsets *
296 chwall_buf->chwall_max_types);
297 running_types =
298 xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
299 conflict_aggregate_set =
300 xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
302 if ((ssids == NULL) || (conflict_sets == NULL)
303 || (running_types == NULL) || (conflict_aggregate_set == NULL))
304 goto error_free;
306 /* 2. set new policy */
307 if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
308 chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs >
309 buf_size)
310 goto error_free;
312 arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
313 sizeof(domaintype_t),
314 chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
316 if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
317 chwall_buf->chwall_max_types *
318 chwall_buf->chwall_max_conflictsets > buf_size)
319 goto error_free;
321 arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
322 sizeof(domaintype_t),
323 chwall_buf->chwall_max_types *
324 chwall_buf->chwall_max_conflictsets);
326 /* we also use new state buffers since max_types can change */
327 memset(running_types, 0,
328 sizeof(domaintype_t) * chwall_buf->chwall_max_types);
329 memset(conflict_aggregate_set, 0,
330 sizeof(domaintype_t) * chwall_buf->chwall_max_types);
332 /* 3. now re-calculate the state for the new policy based on running domains;
333 * this can fail if new policy is conflicting with running domains */
334 if (chwall_init_state(chwall_buf, ssids,
335 conflict_sets, running_types,
336 conflict_aggregate_set))
337 {
338 printk("%s: New policy conflicts with running domains. Policy load aborted.\n",
339 __func__);
340 goto error_free; /* new policy conflicts with running domains */
341 }
342 /* 4. free old policy buffers, replace with new ones */
343 chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
344 chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
345 chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
346 xfree(chwall_bin_pol.ssidrefs);
347 xfree(chwall_bin_pol.conflict_aggregate_set);
348 xfree(chwall_bin_pol.running_types);
349 xfree(chwall_bin_pol.conflict_sets);
350 chwall_bin_pol.ssidrefs = ssids;
351 chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
352 chwall_bin_pol.running_types = running_types;
353 chwall_bin_pol.conflict_sets = conflict_sets;
354 return ACM_OK;
356 error_free:
357 printk("%s: ERROR setting policy.\n", __func__);
358 xfree(ssids);
359 xfree(conflict_sets);
360 xfree(running_types);
361 xfree(conflict_aggregate_set);
362 return -EFAULT;
363 }
365 static int chwall_dump_stats(u8 * buf, u16 len)
366 {
367 /* no stats for Chinese Wall Policy */
368 return 0;
369 }
371 static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len)
372 {
373 int i;
375 /* fill in buffer */
376 if (chwall_bin_pol.max_types > len)
377 return -EFAULT;
379 if (ssidref >= chwall_bin_pol.max_ssidrefs)
380 return -EFAULT;
382 /* read types for chwall ssidref */
383 for (i = 0; i < chwall_bin_pol.max_types; i++)
384 {
385 if (chwall_bin_pol.
386 ssidrefs[ssidref * chwall_bin_pol.max_types + i])
387 buf[i] = 1;
388 else
389 buf[i] = 0;
390 }
391 return chwall_bin_pol.max_types;
392 }
394 /***************************
395 * Authorization functions
396 ***************************/
398 /* -------- DOMAIN OPERATION HOOKS -----------*/
400 static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
401 {
402 ssidref_t chwall_ssidref;
403 int i, j;
404 traceprintk("%s.\n", __func__);
406 read_lock(&acm_bin_pol_rwlock);
407 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
408 if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
409 {
410 printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
411 __func__);
412 read_unlock(&acm_bin_pol_rwlock);
413 return ACM_ACCESS_DENIED; /* catching and indicating config error */
414 }
415 if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
416 {
417 printk("%s: ERROR chwall_ssidref > max(%x).\n",
418 __func__, chwall_bin_pol.max_ssidrefs - 1);
419 read_unlock(&acm_bin_pol_rwlock);
420 return ACM_ACCESS_DENIED;
421 }
422 /* A: chinese wall check for conflicts */
423 for (i = 0; i < chwall_bin_pol.max_types; i++)
424 if (chwall_bin_pol.conflict_aggregate_set[i] &&
425 chwall_bin_pol.ssidrefs[chwall_ssidref *
426 chwall_bin_pol.max_types + i])
427 {
428 printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
429 read_unlock(&acm_bin_pol_rwlock);
430 return ACM_ACCESS_DENIED;
431 }
433 /* B: chinese wall conflict set adjustment (so that other
434 * other domains simultaneously created are evaluated against this new set)*/
435 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
436 {
437 int common = 0;
438 /* check if conflict_set_i and ssidref have common types */
439 for (j = 0; j < chwall_bin_pol.max_types; j++)
440 if (chwall_bin_pol.
441 conflict_sets[i * chwall_bin_pol.max_types + j]
442 && chwall_bin_pol.ssidrefs[chwall_ssidref *
443 chwall_bin_pol.max_types + j])
444 {
445 common = 1;
446 break;
447 }
448 if (common == 0)
449 continue; /* try next conflict set */
450 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
451 for (j = 0; j < chwall_bin_pol.max_types; j++)
452 if (chwall_bin_pol.
453 conflict_sets[i * chwall_bin_pol.max_types + j]
454 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
455 chwall_bin_pol.max_types + j])
456 chwall_bin_pol.conflict_aggregate_set[j]++;
457 }
458 read_unlock(&acm_bin_pol_rwlock);
459 return ACM_ACCESS_PERMITTED;
460 }
462 static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
463 {
464 int i, j;
465 ssidref_t chwall_ssidref;
466 traceprintk("%s.\n", __func__);
468 read_lock(&acm_bin_pol_rwlock);
469 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
470 /* adjust types ref-count for running domains */
471 for (i = 0; i < chwall_bin_pol.max_types; i++)
472 chwall_bin_pol.running_types[i] +=
473 chwall_bin_pol.ssidrefs[chwall_ssidref *
474 chwall_bin_pol.max_types + i];
475 if (domid)
476 {
477 read_unlock(&acm_bin_pol_rwlock);
478 return;
479 }
480 /* Xen does not call pre-create hook for DOM0;
481 * to consider type conflicts of any domain with DOM0, we need
482 * to adjust the conflict_aggregate for DOM0 here the same way it
483 * is done for non-DOM0 domains in the pre-hook */
484 printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n",
485 __func__, ssidref, chwall_ssidref);
487 /* chinese wall conflict set adjustment (so that other
488 * other domains simultaneously created are evaluated against this new set)*/
489 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
490 {
491 int common = 0;
492 /* check if conflict_set_i and ssidref have common types */
493 for (j = 0; j < chwall_bin_pol.max_types; j++)
494 if (chwall_bin_pol.
495 conflict_sets[i * chwall_bin_pol.max_types + j]
496 && chwall_bin_pol.ssidrefs[chwall_ssidref *
497 chwall_bin_pol.max_types + j])
498 {
499 common = 1;
500 break;
501 }
502 if (common == 0)
503 continue; /* try next conflict set */
504 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
505 for (j = 0; j < chwall_bin_pol.max_types; j++)
506 if (chwall_bin_pol.
507 conflict_sets[i * chwall_bin_pol.max_types + j]
508 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
509 chwall_bin_pol.max_types + j])
510 chwall_bin_pol.conflict_aggregate_set[j]++;
511 }
512 read_unlock(&acm_bin_pol_rwlock);
513 return;
514 }
516 static void
517 chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
518 {
519 int i, j;
520 ssidref_t chwall_ssidref;
521 traceprintk("%s.\n", __func__);
523 read_lock(&acm_bin_pol_rwlock);
524 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
525 /* roll-back: re-adjust conflicting types aggregate */
526 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
527 {
528 int common = 0;
529 /* check if conflict_set_i and ssidref have common types */
530 for (j = 0; j < chwall_bin_pol.max_types; j++)
531 if (chwall_bin_pol.
532 conflict_sets[i * chwall_bin_pol.max_types + j]
533 && chwall_bin_pol.ssidrefs[chwall_ssidref *
534 chwall_bin_pol.max_types + j])
535 {
536 common = 1;
537 break;
538 }
539 if (common == 0)
540 continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
541 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
542 for (j = 0; j < chwall_bin_pol.max_types; j++)
543 if (chwall_bin_pol.
544 conflict_sets[i * chwall_bin_pol.max_types + j]
545 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
546 chwall_bin_pol.max_types + j])
547 chwall_bin_pol.conflict_aggregate_set[j]--;
548 }
549 read_unlock(&acm_bin_pol_rwlock);
550 }
553 static void chwall_post_domain_destroy(void *object_ssid, domid_t id)
554 {
555 int i, j;
556 struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
557 (struct acm_ssid_domain *)
558 object_ssid);
559 ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
561 traceprintk("%s.\n", __func__);
563 read_lock(&acm_bin_pol_rwlock);
564 /* adjust running types set */
565 for (i = 0; i < chwall_bin_pol.max_types; i++)
566 chwall_bin_pol.running_types[i] -=
567 chwall_bin_pol.ssidrefs[chwall_ssidref *
568 chwall_bin_pol.max_types + i];
570 /* roll-back: re-adjust conflicting types aggregate */
571 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
572 {
573 int common = 0;
574 /* check if conflict_set_i and ssidref have common types */
575 for (j = 0; j < chwall_bin_pol.max_types; j++)
576 if (chwall_bin_pol.
577 conflict_sets[i * chwall_bin_pol.max_types + j]
578 && chwall_bin_pol.ssidrefs[chwall_ssidref *
579 chwall_bin_pol.max_types + j])
580 {
581 common = 1;
582 break;
583 }
584 if (common == 0)
585 continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
586 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
587 for (j = 0; j < chwall_bin_pol.max_types; j++)
588 if (chwall_bin_pol.
589 conflict_sets[i * chwall_bin_pol.max_types + j]
590 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
591 chwall_bin_pol.max_types + j])
592 chwall_bin_pol.conflict_aggregate_set[j]--;
593 }
594 read_unlock(&acm_bin_pol_rwlock);
595 return;
596 }
598 struct acm_operations acm_chinesewall_ops = {
599 /* policy management services */
600 .init_domain_ssid = chwall_init_domain_ssid,
601 .free_domain_ssid = chwall_free_domain_ssid,
602 .dump_binary_policy = chwall_dump_policy,
603 .set_binary_policy = chwall_set_policy,
604 .dump_statistics = chwall_dump_stats,
605 .dump_ssid_types = chwall_dump_ssid_types,
606 /* domain management control hooks */
607 .pre_domain_create = chwall_pre_domain_create,
608 .post_domain_create = chwall_post_domain_create,
609 .fail_domain_create = chwall_fail_domain_create,
610 .post_domain_destroy = chwall_post_domain_destroy,
611 /* event channel control hooks */
612 .pre_eventchannel_unbound = NULL,
613 .fail_eventchannel_unbound = NULL,
614 .pre_eventchannel_interdomain = NULL,
615 .fail_eventchannel_interdomain = NULL,
616 /* grant table control hooks */
617 .pre_grant_map_ref = NULL,
618 .fail_grant_map_ref = NULL,
619 .pre_grant_setup = NULL,
620 .fail_grant_setup = NULL,
621 /* generic domain-requested decision hooks */
622 .sharing = NULL,
623 };
625 /*
626 * Local variables:
627 * mode: C
628 * c-set-style: "BSD"
629 * c-basic-offset: 4
630 * tab-width: 4
631 * indent-tabs-mode: nil
632 * End:
633 */