ia64/xen-unstable

view xen/include/acm/acm_hooks.h @ 6788:e939d5c5e646

Pass the root directory to Doxyfilter and thence pythfilter.py so that the latter can get the namespace/packages correct.
author ewan@linford.intra
date Tue Sep 13 14:42:21 2005 +0100 (2005-09-13)
parents 291e816acbf4
children b2f4823b6ff0 b35215021b32 9af349b055e5 3233e7ecfa9f
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 */
18 #ifndef _ACM_HOOKS_H
19 #define _ACM_HOOKS_H
21 #include <xen/config.h>
22 #include <xen/errno.h>
23 #include <xen/types.h>
24 #include <xen/lib.h>
25 #include <xen/delay.h>
26 #include <xen/sched.h>
27 #include <xen/multiboot.h>
28 #include <public/acm.h>
29 #include <acm/acm_core.h>
30 #include <public/dom0_ops.h>
31 #include <public/event_channel.h>
32 #include <asm/current.h>
34 /*
35 * HOOK structure and meaning (justifies a few words about our model):
36 *
37 * General idea: every policy-controlled system operation is reflected in a
38 * transaction in the system's security state
39 *
40 * Keeping the security state consistent requires "atomic" transactions.
41 * The name of the hooks to place around policy-controlled transactions
42 * reflects this. If authorizations do not involve security state changes,
43 * then and only then POST and FAIL hooks remain empty since we don't care
44 * about the eventual outcome of the operation from a security viewpoint.
45 *
46 * PURPOSE of hook types:
47 * ======================
48 * PRE-Hooks
49 * a) general authorization to guard a controlled system operation
50 * b) prepare security state change
51 * (means: fail hook must be able to "undo" this)
52 *
53 * POST-Hooks
54 * a) commit prepared state change
55 *
56 * FAIL-Hooks
57 * a) roll-back prepared security state change from PRE-Hook
58 *
59 *
60 * PLACEMENT of hook types:
61 * ========================
62 * PRE-Hooks must be called before a guarded/controlled system operation
63 * is started. They return ACM_ACCESS_PERMITTED, ACM_ACCESS_DENIED or
64 * error. Operation must be aborted if return is not ACM_ACCESS_PERMITTED.
65 *
66 * POST-Hooks must be called after a successful system operation.
67 * There is no return value: commit never fails.
68 *
69 * FAIL-Hooks must be called:
70 * a) if system transaction (operation) fails after calling the PRE-hook
71 * b) if another (secondary) policy denies access in its PRE-Hook
72 * (policy layering is useful but requires additional handling)
73 *
74 * Hook model from a security transaction viewpoint:
75 * start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success
76 * (pre-hook) \ (post-hook)
77 * \
78 * fail
79 * \
80 * \
81 * roll-back
82 * (fail-hook)
83 * \
84 * sys-ops error
85 *
86 */
88 struct acm_operations {
89 /* policy management functions (must always be defined!) */
90 int (*init_domain_ssid) (void **ssid, ssidref_t ssidref);
91 void (*free_domain_ssid) (void *ssid);
92 int (*dump_binary_policy) (u8 *buffer, u16 buf_size);
93 int (*set_binary_policy) (u8 *buffer, u16 buf_size);
94 int (*dump_statistics) (u8 *buffer, u16 buf_size);
95 int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size);
96 /* domain management control hooks (can be NULL) */
97 int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
98 void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
99 void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
100 void (*post_domain_destroy) (void *object_ssid, domid_t id);
101 /* event channel control hooks (can be NULL) */
102 int (*pre_eventchannel_unbound) (domid_t id);
103 void (*fail_eventchannel_unbound) (domid_t id);
104 int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2);
105 int (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
106 /* grant table control hooks (can be NULL) */
107 int (*pre_grant_map_ref) (domid_t id);
108 void (*fail_grant_map_ref) (domid_t id);
109 int (*pre_grant_setup) (domid_t id);
110 void (*fail_grant_setup) (domid_t id);
111 };
113 /* global variables */
114 extern struct acm_operations *acm_primary_ops;
115 extern struct acm_operations *acm_secondary_ops;
117 /* if ACM_TRACE_MODE defined, all hooks should
118 * print a short trace message */
119 /* #define ACM_TRACE_MODE */
121 #ifdef ACM_TRACE_MODE
122 # define traceprintk(fmt, args...) printk(fmt,## args)
123 #else
124 # define traceprintk(fmt, args...)
125 #endif
127 #if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
129 static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
130 { return 0; }
131 static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
132 { return; }
133 static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
134 { return; }
135 static inline int acm_pre_event_channel(evtchn_op_t *op)
136 { return 0; }
137 static inline int acm_pre_grant_map_ref(domid_t id)
138 { return 0; }
139 static inline int acm_pre_grant_setup(domid_t id)
140 { return 0; }
141 static inline int acm_init(unsigned int *initrdidx,
142 const multiboot_info_t *mbi,
143 unsigned long start)
144 { return 0; }
145 static inline void acm_post_domain0_create(domid_t domid)
146 { return; }
148 #else
150 static inline int acm_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
151 {
152 if ((acm_primary_ops->pre_domain_create != NULL) &&
153 acm_primary_ops->pre_domain_create(subject_ssid, ssidref))
154 return ACM_ACCESS_DENIED;
155 else if ((acm_secondary_ops->pre_domain_create != NULL) &&
156 acm_secondary_ops->pre_domain_create(subject_ssid, ssidref)) {
157 /* roll-back primary */
158 if (acm_primary_ops->fail_domain_create != NULL)
159 acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
160 return ACM_ACCESS_DENIED;
161 } else
162 return ACM_ACCESS_PERMITTED;
163 }
165 static inline void acm_post_domain_create(domid_t domid, ssidref_t ssidref)
166 {
167 if (acm_primary_ops->post_domain_create != NULL)
168 acm_primary_ops->post_domain_create(domid, ssidref);
169 if (acm_secondary_ops->post_domain_create != NULL)
170 acm_secondary_ops->post_domain_create(domid, ssidref);
171 }
173 static inline void acm_fail_domain_create(
174 void *subject_ssid, ssidref_t ssidref)
175 {
176 if (acm_primary_ops->fail_domain_create != NULL)
177 acm_primary_ops->fail_domain_create(subject_ssid, ssidref);
178 if (acm_secondary_ops->fail_domain_create != NULL)
179 acm_secondary_ops->fail_domain_create(subject_ssid, ssidref);
180 }
182 static inline void acm_post_domain_destroy(void *object_ssid, domid_t id)
183 {
184 if (acm_primary_ops->post_domain_destroy != NULL)
185 acm_primary_ops->post_domain_destroy(object_ssid, id);
186 if (acm_secondary_ops->post_domain_destroy != NULL)
187 acm_secondary_ops->post_domain_destroy(object_ssid, id);
188 return;
189 }
191 static inline int acm_pre_eventchannel_unbound(domid_t id)
192 {
193 if ((acm_primary_ops->pre_eventchannel_unbound != NULL) &&
194 acm_primary_ops->pre_eventchannel_unbound(id))
195 return ACM_ACCESS_DENIED;
196 else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) &&
197 acm_secondary_ops->pre_eventchannel_unbound(id)) {
198 /* roll-back primary */
199 if (acm_primary_ops->fail_eventchannel_unbound != NULL)
200 acm_primary_ops->fail_eventchannel_unbound(id);
201 return ACM_ACCESS_DENIED;
202 } else
203 return ACM_ACCESS_PERMITTED;
204 }
206 static inline int acm_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
207 {
208 if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
209 acm_primary_ops->pre_eventchannel_interdomain(id1, id2))
210 return ACM_ACCESS_DENIED;
211 else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
212 acm_secondary_ops->pre_eventchannel_interdomain(id1, id2)) {
213 /* roll-back primary */
214 if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
215 acm_primary_ops->fail_eventchannel_interdomain(id1, id2);
216 return ACM_ACCESS_DENIED;
217 } else
218 return ACM_ACCESS_PERMITTED;
219 }
221 static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
222 {
223 int ret = -EACCES;
224 struct domain *d;
226 switch(op->cmd) {
227 case DOM0_CREATEDOMAIN:
228 ret = acm_pre_domain_create(
229 current->domain->ssid, op->u.createdomain.ssidref);
230 break;
231 case DOM0_DESTROYDOMAIN:
232 d = find_domain_by_id(op->u.destroydomain.domain);
233 if (d != NULL) {
234 *ssid = d->ssid; /* save for post destroy when d is gone */
235 /* no policy-specific hook */
236 put_domain(d);
237 ret = 0;
238 }
239 break;
240 default:
241 ret = 0; /* ok */
242 }
243 return ret;
244 }
246 static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
247 {
248 switch(op->cmd) {
249 case DOM0_CREATEDOMAIN:
250 /* initialialize shared sHype security labels for new domain */
251 acm_init_domain_ssid(
252 op->u.createdomain.domain, op->u.createdomain.ssidref);
253 acm_post_domain_create(
254 op->u.createdomain.domain, op->u.createdomain.ssidref);
255 break;
256 case DOM0_DESTROYDOMAIN:
257 acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
258 /* free security ssid for the destroyed domain (also if null policy */
259 acm_free_domain_ssid((struct acm_ssid_domain *)ssid);
260 break;
261 }
262 }
264 static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
265 {
266 switch(op->cmd) {
267 case DOM0_CREATEDOMAIN:
268 acm_fail_domain_create(
269 current->domain->ssid, op->u.createdomain.ssidref);
270 break;
271 }
272 }
274 static inline int acm_pre_event_channel(evtchn_op_t *op)
275 {
276 int ret = -EACCES;
278 switch(op->cmd) {
279 case EVTCHNOP_alloc_unbound:
280 ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom);
281 break;
282 case EVTCHNOP_bind_interdomain:
283 ret = acm_pre_eventchannel_interdomain(
284 op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2);
285 break;
286 default:
287 ret = 0; /* ok */
288 }
289 return ret;
290 }
292 static inline int acm_pre_grant_map_ref(domid_t id)
293 {
294 if ( (acm_primary_ops->pre_grant_map_ref != NULL) &&
295 acm_primary_ops->pre_grant_map_ref(id) )
296 {
297 return ACM_ACCESS_DENIED;
298 }
299 else if ( (acm_secondary_ops->pre_grant_map_ref != NULL) &&
300 acm_secondary_ops->pre_grant_map_ref(id) )
301 {
302 /* roll-back primary */
303 if ( acm_primary_ops->fail_grant_map_ref != NULL )
304 acm_primary_ops->fail_grant_map_ref(id);
305 return ACM_ACCESS_DENIED;
306 }
307 else
308 {
309 return ACM_ACCESS_PERMITTED;
310 }
311 }
313 static inline int acm_pre_grant_setup(domid_t id)
314 {
315 if ( (acm_primary_ops->pre_grant_setup != NULL) &&
316 acm_primary_ops->pre_grant_setup(id) )
317 {
318 return ACM_ACCESS_DENIED;
319 }
320 else if ( (acm_secondary_ops->pre_grant_setup != NULL) &&
321 acm_secondary_ops->pre_grant_setup(id) )
322 {
323 /* roll-back primary */
324 if (acm_primary_ops->fail_grant_setup != NULL)
325 acm_primary_ops->fail_grant_setup(id);
326 return ACM_ACCESS_DENIED;
327 }
328 else
329 {
330 return ACM_ACCESS_PERMITTED;
331 }
332 }
334 /* predefined ssidref for DOM0 used by xen when creating DOM0 */
335 #define ACM_DOM0_SSIDREF 0x00010001
337 static inline void acm_post_domain0_create(domid_t domid)
338 {
339 /* initialialize shared sHype security labels for new domain */
340 acm_init_domain_ssid(domid, ACM_DOM0_SSIDREF);
341 acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
342 }
344 extern int acm_init(unsigned int *initrdidx,
345 const multiboot_info_t *mbi,
346 unsigned long start);
348 #endif
350 #endif