ia64/xen-unstable

view xen/acm/acm_chinesewall_hooks.c @ 11901:d088aec406c0

[ACM] Add missing alignment operations for the ACM module.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kfraser@localhost.localdomain
date Thu Oct 19 15:14:25 2006 +0100 (2006-10-19)
parents fcb7e5616102
children 699656fb1d0b
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 ret = (ret + 7) & ~7;
159 if (buf_size < ret)
160 return -EINVAL;
162 /* now copy buffers over */
163 arrcpy16((u16 *) (buf + ntohl(chwall_buf->chwall_ssid_offset)),
164 chwall_bin_pol.ssidrefs,
165 chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
167 arrcpy16((u16 *) (buf +
168 ntohl(chwall_buf->chwall_conflict_sets_offset)),
169 chwall_bin_pol.conflict_sets,
170 chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
172 arrcpy16((u16 *) (buf +
173 ntohl(chwall_buf->chwall_running_types_offset)),
174 chwall_bin_pol.running_types, chwall_bin_pol.max_types);
176 arrcpy16((u16 *) (buf +
177 ntohl(chwall_buf->chwall_conflict_aggregate_offset)),
178 chwall_bin_pol.conflict_aggregate_set,
179 chwall_bin_pol.max_types);
180 return ret;
181 }
183 /* adapt security state (running_types and conflict_aggregate_set) to all running
184 * domains; chwall_init_state is called when a policy is changed to bring the security
185 * information into a consistent state and to detect violations (return != 0).
186 * from a security point of view, we simulate that all running domains are re-started
187 */
188 static int
189 chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
190 domaintype_t * ssidrefs, domaintype_t * conflict_sets,
191 domaintype_t * running_types,
192 domaintype_t * conflict_aggregate_set)
193 {
194 int violation = 0, i, j;
195 struct chwall_ssid *chwall_ssid;
196 ssidref_t chwall_ssidref;
197 struct domain **pd;
199 write_lock(&domlist_lock);
200 /* go through all domains and adjust policy as if this domain was started now */
201 pd = &domain_list;
202 for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list)
203 {
204 chwall_ssid =
205 GET_SSIDP(ACM_CHINESE_WALL_POLICY,
206 (struct acm_ssid_domain *) (*pd)->ssid);
207 chwall_ssidref = chwall_ssid->chwall_ssidref;
208 traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
209 __func__, (*pd)->domain_id, chwall_ssidref);
210 /* a) adjust types ref-count for running domains */
211 for (i = 0; i < chwall_buf->chwall_max_types; i++)
212 running_types[i] +=
213 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i];
215 /* b) check for conflict */
216 for (i = 0; i < chwall_buf->chwall_max_types; i++)
217 if (conflict_aggregate_set[i] &&
218 ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i])
219 {
220 printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
221 __func__, i);
222 violation = 1;
223 goto out;
224 }
225 /* set violation and break out of the loop */
226 /* c) adapt conflict aggregate set for this domain (notice conflicts) */
227 for (i = 0; i < chwall_buf->chwall_max_conflictsets; i++)
228 {
229 int common = 0;
230 /* check if conflict_set_i and ssidref have common types */
231 for (j = 0; j < chwall_buf->chwall_max_types; j++)
232 if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
233 ssidrefs[chwall_ssidref *
234 chwall_buf->chwall_max_types + j])
235 {
236 common = 1;
237 break;
238 }
239 if (common == 0)
240 continue; /* try next conflict set */
241 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
242 for (j = 0; j < chwall_buf->chwall_max_types; j++)
243 if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
244 !ssidrefs[chwall_ssidref *
245 chwall_buf->chwall_max_types + j])
246 conflict_aggregate_set[j]++;
247 }
248 }
249 out:
250 write_unlock(&domlist_lock);
251 return violation;
252 /* returning "violation != 0" means that the currently running set of domains would
253 * not be possible if the new policy had been enforced before starting them; for chinese
254 * wall, this means that the new policy includes at least one conflict set of which
255 * more than one type is currently running */
256 }
258 static int chwall_set_policy(u8 * buf, u32 buf_size)
259 {
260 /* policy write-locked already */
261 struct acm_chwall_policy_buffer *chwall_buf =
262 (struct acm_chwall_policy_buffer *) buf;
263 void *ssids = NULL, *conflict_sets = NULL, *running_types =
264 NULL, *conflict_aggregate_set = NULL;
266 if (buf_size < sizeof(struct acm_chwall_policy_buffer))
267 return -EINVAL;
269 /* rewrite the policy due to endianess */
270 chwall_buf->policy_code = ntohl(chwall_buf->policy_code);
271 chwall_buf->policy_version = ntohl(chwall_buf->policy_version);
272 chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types);
273 chwall_buf->chwall_max_ssidrefs =
274 ntohl(chwall_buf->chwall_max_ssidrefs);
275 chwall_buf->chwall_max_conflictsets =
276 ntohl(chwall_buf->chwall_max_conflictsets);
277 chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset);
278 chwall_buf->chwall_conflict_sets_offset =
279 ntohl(chwall_buf->chwall_conflict_sets_offset);
280 chwall_buf->chwall_running_types_offset =
281 ntohl(chwall_buf->chwall_running_types_offset);
282 chwall_buf->chwall_conflict_aggregate_offset =
283 ntohl(chwall_buf->chwall_conflict_aggregate_offset);
285 /* policy type and version checks */
286 if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
287 (chwall_buf->policy_version != ACM_CHWALL_VERSION))
288 return -EINVAL;
290 /* 1. allocate new buffers */
291 ssids =
292 xmalloc_array(domaintype_t,
293 chwall_buf->chwall_max_types *
294 chwall_buf->chwall_max_ssidrefs);
295 conflict_sets =
296 xmalloc_array(domaintype_t,
297 chwall_buf->chwall_max_conflictsets *
298 chwall_buf->chwall_max_types);
299 running_types =
300 xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
301 conflict_aggregate_set =
302 xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
304 if ((ssids == NULL) || (conflict_sets == NULL)
305 || (running_types == NULL) || (conflict_aggregate_set == NULL))
306 goto error_free;
308 /* 2. set new policy */
309 if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
310 chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs >
311 buf_size)
312 goto error_free;
314 arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
315 sizeof(domaintype_t),
316 chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
318 if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
319 chwall_buf->chwall_max_types *
320 chwall_buf->chwall_max_conflictsets > buf_size)
321 goto error_free;
323 arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
324 sizeof(domaintype_t),
325 chwall_buf->chwall_max_types *
326 chwall_buf->chwall_max_conflictsets);
328 /* we also use new state buffers since max_types can change */
329 memset(running_types, 0,
330 sizeof(domaintype_t) * chwall_buf->chwall_max_types);
331 memset(conflict_aggregate_set, 0,
332 sizeof(domaintype_t) * chwall_buf->chwall_max_types);
334 /* 3. now re-calculate the state for the new policy based on running domains;
335 * this can fail if new policy is conflicting with running domains */
336 if (chwall_init_state(chwall_buf, ssids,
337 conflict_sets, running_types,
338 conflict_aggregate_set))
339 {
340 printk("%s: New policy conflicts with running domains. Policy load aborted.\n",
341 __func__);
342 goto error_free; /* new policy conflicts with running domains */
343 }
344 /* 4. free old policy buffers, replace with new ones */
345 chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
346 chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
347 chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
348 xfree(chwall_bin_pol.ssidrefs);
349 xfree(chwall_bin_pol.conflict_aggregate_set);
350 xfree(chwall_bin_pol.running_types);
351 xfree(chwall_bin_pol.conflict_sets);
352 chwall_bin_pol.ssidrefs = ssids;
353 chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
354 chwall_bin_pol.running_types = running_types;
355 chwall_bin_pol.conflict_sets = conflict_sets;
356 return ACM_OK;
358 error_free:
359 printk("%s: ERROR setting policy.\n", __func__);
360 xfree(ssids);
361 xfree(conflict_sets);
362 xfree(running_types);
363 xfree(conflict_aggregate_set);
364 return -EFAULT;
365 }
367 static int chwall_dump_stats(u8 * buf, u16 len)
368 {
369 /* no stats for Chinese Wall Policy */
370 return 0;
371 }
373 static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len)
374 {
375 int i;
377 /* fill in buffer */
378 if (chwall_bin_pol.max_types > len)
379 return -EFAULT;
381 if (ssidref >= chwall_bin_pol.max_ssidrefs)
382 return -EFAULT;
384 /* read types for chwall ssidref */
385 for (i = 0; i < chwall_bin_pol.max_types; i++)
386 {
387 if (chwall_bin_pol.
388 ssidrefs[ssidref * chwall_bin_pol.max_types + i])
389 buf[i] = 1;
390 else
391 buf[i] = 0;
392 }
393 return chwall_bin_pol.max_types;
394 }
396 /***************************
397 * Authorization functions
398 ***************************/
400 /* -------- DOMAIN OPERATION HOOKS -----------*/
402 static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
403 {
404 ssidref_t chwall_ssidref;
405 int i, j;
406 traceprintk("%s.\n", __func__);
408 read_lock(&acm_bin_pol_rwlock);
409 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
410 if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
411 {
412 printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
413 __func__);
414 read_unlock(&acm_bin_pol_rwlock);
415 return ACM_ACCESS_DENIED; /* catching and indicating config error */
416 }
417 if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
418 {
419 printk("%s: ERROR chwall_ssidref > max(%x).\n",
420 __func__, chwall_bin_pol.max_ssidrefs - 1);
421 read_unlock(&acm_bin_pol_rwlock);
422 return ACM_ACCESS_DENIED;
423 }
424 /* A: chinese wall check for conflicts */
425 for (i = 0; i < chwall_bin_pol.max_types; i++)
426 if (chwall_bin_pol.conflict_aggregate_set[i] &&
427 chwall_bin_pol.ssidrefs[chwall_ssidref *
428 chwall_bin_pol.max_types + i])
429 {
430 printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
431 read_unlock(&acm_bin_pol_rwlock);
432 return ACM_ACCESS_DENIED;
433 }
435 /* B: chinese wall conflict set adjustment (so that other
436 * other domains simultaneously created are evaluated against this new set)*/
437 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
438 {
439 int common = 0;
440 /* check if conflict_set_i and ssidref have common types */
441 for (j = 0; j < chwall_bin_pol.max_types; j++)
442 if (chwall_bin_pol.
443 conflict_sets[i * chwall_bin_pol.max_types + j]
444 && chwall_bin_pol.ssidrefs[chwall_ssidref *
445 chwall_bin_pol.max_types + j])
446 {
447 common = 1;
448 break;
449 }
450 if (common == 0)
451 continue; /* try next conflict set */
452 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
453 for (j = 0; j < chwall_bin_pol.max_types; j++)
454 if (chwall_bin_pol.
455 conflict_sets[i * chwall_bin_pol.max_types + j]
456 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
457 chwall_bin_pol.max_types + j])
458 chwall_bin_pol.conflict_aggregate_set[j]++;
459 }
460 read_unlock(&acm_bin_pol_rwlock);
461 return ACM_ACCESS_PERMITTED;
462 }
464 static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
465 {
466 int i, j;
467 ssidref_t chwall_ssidref;
468 traceprintk("%s.\n", __func__);
470 read_lock(&acm_bin_pol_rwlock);
471 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
472 /* adjust types ref-count for running domains */
473 for (i = 0; i < chwall_bin_pol.max_types; i++)
474 chwall_bin_pol.running_types[i] +=
475 chwall_bin_pol.ssidrefs[chwall_ssidref *
476 chwall_bin_pol.max_types + i];
477 if (domid)
478 {
479 read_unlock(&acm_bin_pol_rwlock);
480 return;
481 }
482 /* Xen does not call pre-create hook for DOM0;
483 * to consider type conflicts of any domain with DOM0, we need
484 * to adjust the conflict_aggregate for DOM0 here the same way it
485 * is done for non-DOM0 domains in the pre-hook */
486 printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n",
487 __func__, ssidref, chwall_ssidref);
489 /* chinese wall conflict set adjustment (so that other
490 * other domains simultaneously created are evaluated against this new set)*/
491 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
492 {
493 int common = 0;
494 /* check if conflict_set_i and ssidref have common types */
495 for (j = 0; j < chwall_bin_pol.max_types; j++)
496 if (chwall_bin_pol.
497 conflict_sets[i * chwall_bin_pol.max_types + j]
498 && chwall_bin_pol.ssidrefs[chwall_ssidref *
499 chwall_bin_pol.max_types + j])
500 {
501 common = 1;
502 break;
503 }
504 if (common == 0)
505 continue; /* try next conflict set */
506 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
507 for (j = 0; j < chwall_bin_pol.max_types; j++)
508 if (chwall_bin_pol.
509 conflict_sets[i * chwall_bin_pol.max_types + j]
510 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
511 chwall_bin_pol.max_types + j])
512 chwall_bin_pol.conflict_aggregate_set[j]++;
513 }
514 read_unlock(&acm_bin_pol_rwlock);
515 return;
516 }
518 static void
519 chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
520 {
521 int i, j;
522 ssidref_t chwall_ssidref;
523 traceprintk("%s.\n", __func__);
525 read_lock(&acm_bin_pol_rwlock);
526 chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
527 /* roll-back: re-adjust conflicting types aggregate */
528 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
529 {
530 int common = 0;
531 /* check if conflict_set_i and ssidref have common types */
532 for (j = 0; j < chwall_bin_pol.max_types; j++)
533 if (chwall_bin_pol.
534 conflict_sets[i * chwall_bin_pol.max_types + j]
535 && chwall_bin_pol.ssidrefs[chwall_ssidref *
536 chwall_bin_pol.max_types + j])
537 {
538 common = 1;
539 break;
540 }
541 if (common == 0)
542 continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
543 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
544 for (j = 0; j < chwall_bin_pol.max_types; j++)
545 if (chwall_bin_pol.
546 conflict_sets[i * chwall_bin_pol.max_types + j]
547 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
548 chwall_bin_pol.max_types + j])
549 chwall_bin_pol.conflict_aggregate_set[j]--;
550 }
551 read_unlock(&acm_bin_pol_rwlock);
552 }
555 static void chwall_post_domain_destroy(void *object_ssid, domid_t id)
556 {
557 int i, j;
558 struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
559 (struct acm_ssid_domain *)
560 object_ssid);
561 ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
563 traceprintk("%s.\n", __func__);
565 read_lock(&acm_bin_pol_rwlock);
566 /* adjust running types set */
567 for (i = 0; i < chwall_bin_pol.max_types; i++)
568 chwall_bin_pol.running_types[i] -=
569 chwall_bin_pol.ssidrefs[chwall_ssidref *
570 chwall_bin_pol.max_types + i];
572 /* roll-back: re-adjust conflicting types aggregate */
573 for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
574 {
575 int common = 0;
576 /* check if conflict_set_i and ssidref have common types */
577 for (j = 0; j < chwall_bin_pol.max_types; j++)
578 if (chwall_bin_pol.
579 conflict_sets[i * chwall_bin_pol.max_types + j]
580 && chwall_bin_pol.ssidrefs[chwall_ssidref *
581 chwall_bin_pol.max_types + j])
582 {
583 common = 1;
584 break;
585 }
586 if (common == 0)
587 continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
588 /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
589 for (j = 0; j < chwall_bin_pol.max_types; j++)
590 if (chwall_bin_pol.
591 conflict_sets[i * chwall_bin_pol.max_types + j]
592 && !chwall_bin_pol.ssidrefs[chwall_ssidref *
593 chwall_bin_pol.max_types + j])
594 chwall_bin_pol.conflict_aggregate_set[j]--;
595 }
596 read_unlock(&acm_bin_pol_rwlock);
597 return;
598 }
600 struct acm_operations acm_chinesewall_ops = {
601 /* policy management services */
602 .init_domain_ssid = chwall_init_domain_ssid,
603 .free_domain_ssid = chwall_free_domain_ssid,
604 .dump_binary_policy = chwall_dump_policy,
605 .set_binary_policy = chwall_set_policy,
606 .dump_statistics = chwall_dump_stats,
607 .dump_ssid_types = chwall_dump_ssid_types,
608 /* domain management control hooks */
609 .pre_domain_create = chwall_pre_domain_create,
610 .post_domain_create = chwall_post_domain_create,
611 .fail_domain_create = chwall_fail_domain_create,
612 .post_domain_destroy = chwall_post_domain_destroy,
613 /* event channel control hooks */
614 .pre_eventchannel_unbound = NULL,
615 .fail_eventchannel_unbound = NULL,
616 .pre_eventchannel_interdomain = NULL,
617 .fail_eventchannel_interdomain = NULL,
618 /* grant table control hooks */
619 .pre_grant_map_ref = NULL,
620 .fail_grant_map_ref = NULL,
621 .pre_grant_setup = NULL,
622 .fail_grant_setup = NULL,
623 /* generic domain-requested decision hooks */
624 .sharing = NULL,
625 };
627 /*
628 * Local variables:
629 * mode: C
630 * c-set-style: "BSD"
631 * c-basic-offset: 4
632 * tab-width: 4
633 * indent-tabs-mode: nil
634 * End:
635 */