ia64/xen-unstable

view xen/include/acm/acm_hooks.h @ 8614:bd606783c6bf

remove unnecessary macro bdev_put which is an alias to blkdev_put.

Signed-off-by: Vincent Hanquez <vincent@xensource.com>
author vhanquez@kneesa.uk.xensource.com
date Mon Jan 16 21:13:29 2006 +0000 (2006-01-16)
parents cc1d77bba4b0
children 98c8afe4c433
line source
1 /****************************************************************
2 * acm_hooks.h
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 * acm header file implementing the global (policy-independent)
15 * sHype hooks that are called throughout Xen.
16 *
17 */
19 #ifndef _ACM_HOOKS_H
20 #define _ACM_HOOKS_H
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 <xen/multiboot.h>
29 #include <public/acm.h>
30 #include <acm/acm_core.h>
31 #include <public/dom0_ops.h>
32 #include <public/event_channel.h>
33 #include <asm/current.h>
35 /*
36 * HOOK structure and meaning (justifies a few words about our model):
37 *
38 * General idea: every policy-controlled system operation is reflected in a
39 * transaction in the system's security state
40 *
41 * Keeping the security state consistent requires "atomic" transactions.
42 * The name of the hooks to place around policy-controlled transactions
43 * reflects this. If authorizations do not involve security state changes,
44 * then and only then POST and FAIL hooks remain empty since we don't care
45 * about the eventual outcome of the operation from a security viewpoint.
46 *
47 * PURPOSE of hook types:
48 * ======================
49 * PRE-Hooks
50 * a) general authorization to guard a controlled system operation
51 * b) prepare security state change
52 * (means: fail hook must be able to "undo" this)
53 *
54 * POST-Hooks
55 * a) commit prepared state change
56 *
57 * FAIL-Hooks
58 * a) roll-back prepared security state change from PRE-Hook
59 *
60 *
61 * PLACEMENT of hook types:
62 * ========================
63 * PRE-Hooks must be called before a guarded/controlled system operation
64 * is started. They return ACM_ACCESS_PERMITTED, ACM_ACCESS_DENIED or
65 * error. Operation must be aborted if return is not ACM_ACCESS_PERMITTED.
66 *
67 * POST-Hooks must be called after a successful system operation.
68 * There is no return value: commit never fails.
69 *
70 * FAIL-Hooks must be called:
71 * a) if system transaction (operation) fails after calling the PRE-hook
72 * b) if another (secondary) policy denies access in its PRE-Hook
73 * (policy layering is useful but requires additional handling)
74 *
75 * Hook model from a security transaction viewpoint:
76 * start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success
77 * (pre-hook) \ (post-hook)
78 * \
79 * fail
80 * \
81 * \
82 * roll-back
83 * (fail-hook)
84 * \
85 * sys-ops error
86 *
87 */
89 struct acm_operations {
90 /* policy management functions (must always be defined!) */
91 int (*init_domain_ssid) (void **ssid, ssidref_t ssidref);
92 void (*free_domain_ssid) (void *ssid);
93 int (*dump_binary_policy) (u8 *buffer, u32 buf_size);
94 int (*set_binary_policy) (u8 *buffer, u32 buf_size);
95 int (*dump_statistics) (u8 *buffer, u16 buf_size);
96 int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size);
97 /* domain management control hooks (can be NULL) */
98 int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
99 void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
100 void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
101 void (*post_domain_destroy) (void *object_ssid, domid_t id);
102 /* event channel control hooks (can be NULL) */
103 int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2);
104 void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2);
105 int (*pre_eventchannel_interdomain) (domid_t id);
106 void (*fail_eventchannel_interdomain) (domid_t id);
107 /* grant table control hooks (can be NULL) */
108 int (*pre_grant_map_ref) (domid_t id);
109 void (*fail_grant_map_ref) (domid_t id);
110 int (*pre_grant_setup) (domid_t id);
111 void (*fail_grant_setup) (domid_t id);
112 /* generic domain-requested decision hooks (can be NULL) */
113 int (*sharing) (ssidref_t ssidref1, ssidref_t ssidref2);
114 };
116 /* global variables */
117 extern struct acm_operations *acm_primary_ops;
118 extern struct acm_operations *acm_secondary_ops;
120 /* if ACM_TRACE_MODE defined, all hooks should
121 * print a short trace message */
122 /* #define ACM_TRACE_MODE */
124 #ifdef ACM_TRACE_MODE
125 # define traceprintk(fmt, args...) printk(fmt,## args)
126 #else
127 # define traceprintk(fmt, args...)
128 #endif
130 #ifndef ACM_SECURITY
132 static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
133 { return 0; }
134 static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
135 { return; }
136 static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
137 { return; }
138 static inline int acm_pre_event_channel(evtchn_op_t *op)
139 { return 0; }
140 static inline int acm_pre_grant_map_ref(domid_t id)
141 { return 0; }
142 static inline int acm_pre_grant_setup(domid_t id)
143 { return 0; }
144 static inline int acm_init(unsigned int *initrdidx,
145 const multiboot_info_t *mbi,
146 unsigned long start)
147 { return 0; }
148 static inline void acm_post_domain0_create(domid_t domid)
149 { return; }
150 static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
151 { return 0; }
153 #else
155 static inline int acm_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
156 {
157 if ((acm_primary_ops->pre_domain_create != NULL) &&
158 acm_primary_ops->pre_domain_create(subject_ssid, ssidref))
159 return ACM_ACCESS_DENIED;
160 else if ((acm_secondary_ops->pre_domain_create != NULL) &&
161 acm_secondary_ops->pre_domain_create(subject_ssid, ssidref)) {
162 /* roll-back primary */
163 if (acm_primary_ops->fail_domain_create != NULL)
164 acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
165 return ACM_ACCESS_DENIED;
166 } else
167 return ACM_ACCESS_PERMITTED;
168 }
170 static inline void acm_post_domain_create(domid_t domid, ssidref_t ssidref)
171 {
172 if (acm_primary_ops->post_domain_create != NULL)
173 acm_primary_ops->post_domain_create(domid, ssidref);
174 if (acm_secondary_ops->post_domain_create != NULL)
175 acm_secondary_ops->post_domain_create(domid, ssidref);
176 }
178 static inline void acm_fail_domain_create(
179 void *subject_ssid, ssidref_t ssidref)
180 {
181 if (acm_primary_ops->fail_domain_create != NULL)
182 acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
183 if (acm_secondary_ops->fail_domain_create != NULL)
184 acm_secondary_ops->fail_domain_create(subject_ssid, ssidref);
185 }
187 static inline void acm_post_domain_destroy(void *object_ssid, domid_t id)
188 {
189 if (acm_primary_ops->post_domain_destroy != NULL)
190 acm_primary_ops->post_domain_destroy(object_ssid, id);
191 if (acm_secondary_ops->post_domain_destroy != NULL)
192 acm_secondary_ops->post_domain_destroy(object_ssid, id);
193 return;
194 }
196 static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
197 {
198 if ((acm_primary_ops->pre_eventchannel_unbound != NULL) &&
199 acm_primary_ops->pre_eventchannel_unbound(id1, id2))
200 return ACM_ACCESS_DENIED;
201 else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) &&
202 acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) {
203 /* roll-back primary */
204 if (acm_primary_ops->fail_eventchannel_unbound != NULL)
205 acm_primary_ops->fail_eventchannel_unbound(id1, id2);
206 return ACM_ACCESS_DENIED;
207 } else
208 return ACM_ACCESS_PERMITTED;
209 }
211 static inline int acm_pre_eventchannel_interdomain(domid_t id)
212 {
213 if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
214 acm_primary_ops->pre_eventchannel_interdomain(id))
215 return ACM_ACCESS_DENIED;
216 else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
217 acm_secondary_ops->pre_eventchannel_interdomain(id)) {
218 /* roll-back primary */
219 if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
220 acm_primary_ops->fail_eventchannel_interdomain(id);
221 return ACM_ACCESS_DENIED;
222 } else
223 return ACM_ACCESS_PERMITTED;
224 }
226 static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
227 {
228 int ret = -EACCES;
229 struct domain *d;
231 switch(op->cmd) {
232 case DOM0_CREATEDOMAIN:
233 ret = acm_pre_domain_create(
234 current->domain->ssid, op->u.createdomain.ssidref);
235 break;
236 case DOM0_DESTROYDOMAIN:
237 if (*ssid != NULL) {
238 printkd("%s: Warning. Overlapping destruction.\n",
239 __func__);
240 return -EACCES;
241 }
242 d = find_domain_by_id(op->u.destroydomain.domain);
243 if (d != NULL) {
244 *ssid = d->ssid; /* save for post destroy when d is gone */
245 if (*ssid == NULL) {
246 printk("%s: Warning. Destroying domain without ssid pointer.\n",
247 __func__);
248 put_domain(d);
249 return -EACCES;
250 }
251 d->ssid = NULL; /* make sure it's not used any more */
252 /* no policy-specific hook */
253 put_domain(d);
254 ret = 0;
255 }
256 break;
257 default:
258 ret = 0; /* ok */
259 }
260 return ret;
261 }
263 static inline void acm_post_dom0_op(dom0_op_t *op, void **ssid)
264 {
265 switch(op->cmd) {
266 case DOM0_CREATEDOMAIN:
267 /* initialialize shared sHype security labels for new domain */
268 acm_init_domain_ssid(
269 op->u.createdomain.domain, op->u.createdomain.ssidref);
270 acm_post_domain_create(
271 op->u.createdomain.domain, op->u.createdomain.ssidref);
272 break;
273 case DOM0_DESTROYDOMAIN:
274 acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
275 /* free security ssid for the destroyed domain (also if null policy */
276 acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
277 *ssid = NULL;
278 break;
279 }
280 }
282 static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
283 {
284 switch(op->cmd) {
285 case DOM0_CREATEDOMAIN:
286 acm_fail_domain_create(
287 current->domain->ssid, op->u.createdomain.ssidref);
288 break;
289 }
290 }
292 static inline int acm_pre_event_channel(evtchn_op_t *op)
293 {
294 int ret = -EACCES;
296 switch(op->cmd) {
297 case EVTCHNOP_alloc_unbound:
298 ret = acm_pre_eventchannel_unbound(
299 op->u.alloc_unbound.dom,
300 op->u.alloc_unbound.remote_dom);
301 break;
302 case EVTCHNOP_bind_interdomain:
303 ret = acm_pre_eventchannel_interdomain(
304 op->u.bind_interdomain.remote_dom);
305 break;
306 default:
307 ret = 0; /* ok */
308 }
309 return ret;
310 }
312 static inline int acm_pre_grant_map_ref(domid_t id)
313 {
314 if ( (acm_primary_ops->pre_grant_map_ref != NULL) &&
315 acm_primary_ops->pre_grant_map_ref(id) )
316 {
317 return ACM_ACCESS_DENIED;
318 }
319 else if ( (acm_secondary_ops->pre_grant_map_ref != NULL) &&
320 acm_secondary_ops->pre_grant_map_ref(id) )
321 {
322 /* roll-back primary */
323 if ( acm_primary_ops->fail_grant_map_ref != NULL )
324 acm_primary_ops->fail_grant_map_ref(id);
325 return ACM_ACCESS_DENIED;
326 }
327 else
328 {
329 return ACM_ACCESS_PERMITTED;
330 }
331 }
333 static inline int acm_pre_grant_setup(domid_t id)
334 {
335 if ( (acm_primary_ops->pre_grant_setup != NULL) &&
336 acm_primary_ops->pre_grant_setup(id) )
337 {
338 return ACM_ACCESS_DENIED;
339 }
340 else if ( (acm_secondary_ops->pre_grant_setup != NULL) &&
341 acm_secondary_ops->pre_grant_setup(id) )
342 {
343 /* roll-back primary */
344 if (acm_primary_ops->fail_grant_setup != NULL)
345 acm_primary_ops->fail_grant_setup(id);
346 return ACM_ACCESS_DENIED;
347 }
348 else
349 {
350 return ACM_ACCESS_PERMITTED;
351 }
352 }
354 /* predefined ssidref for DOM0 used by xen when creating DOM0 */
355 #define ACM_DOM0_SSIDREF 0x00010001
357 static inline void acm_post_domain0_create(domid_t domid)
358 {
359 /* initialialize shared sHype security labels for new domain */
360 acm_init_domain_ssid(domid, ACM_DOM0_SSIDREF);
361 acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
362 }
364 static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
365 {
366 if ((acm_primary_ops->sharing != NULL) &&
367 acm_primary_ops->sharing(ssidref1, ssidref2))
368 return ACM_ACCESS_DENIED;
369 else if ((acm_secondary_ops->sharing != NULL) &&
370 acm_secondary_ops->sharing(ssidref1, ssidref2)) {
371 return ACM_ACCESS_DENIED;
372 } else
373 return ACM_ACCESS_PERMITTED;
374 }
376 extern int acm_init(unsigned int *initrdidx,
377 const multiboot_info_t *mbi,
378 unsigned long start);
380 #endif
382 #endif
384 /*
385 * Local variables:
386 * mode: C
387 * c-set-style: "BSD"
388 * c-basic-offset: 4
389 * tab-width: 4
390 * indent-tabs-mode: nil
391 * End:
392 */