ia64/xen-unstable

view xen/acm/acm_policy.c @ 10123:d9f63f9361c4

[LOADER] Another change to the elf_paddr_offset/virt_base logic.
This avoids using zero to indicate 'undefined'. Instead we use
an explicit boolean to indicate whether suitable defaults should
be used. As well as making the logic clearer (I believe) it also
avoids problems if anyone ever explicitly specifies virt_base
(and also elf_paddr_offset) as zero.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun May 21 18:55:14 2006 +0100 (2006-05-21)
parents 0a5183b3e7bb
children c1163951ee2f
line source
1 /****************************************************************
2 * acm_policy.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 policy management for Xen.
18 * This interface allows policy tools in authorized
19 * domains to interact with the Xen access control module
20 *
21 */
23 #include <xen/config.h>
24 #include <xen/errno.h>
25 #include <xen/types.h>
26 #include <xen/lib.h>
27 #include <xen/delay.h>
28 #include <xen/sched.h>
29 #include <acm/acm_core.h>
30 #include <public/acm_ops.h>
31 #include <acm/acm_hooks.h>
32 #include <acm/acm_endian.h>
34 int
35 acm_set_policy(void *buf, u32 buf_size, int isuserbuffer)
36 {
37 u8 *policy_buffer = NULL;
38 struct acm_policy_buffer *pol;
40 if (buf_size < sizeof(struct acm_policy_buffer))
41 return -EFAULT;
43 /* 1. copy buffer from domain */
44 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
45 return -ENOMEM;
47 if (isuserbuffer) {
48 if (copy_from_user(policy_buffer, buf, buf_size))
49 {
50 printk("%s: Error copying!\n",__func__);
51 goto error_free;
52 }
53 } else
54 memcpy(policy_buffer, buf, buf_size);
56 /* 2. some sanity checking */
57 pol = (struct acm_policy_buffer *)policy_buffer;
59 if ((ntohl(pol->magic) != ACM_MAGIC) ||
60 (buf_size != ntohl(pol->len)) ||
61 (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
62 {
63 printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
64 goto error_free;
65 }
67 if (acm_active_security_policy == ACM_POLICY_UNDEFINED) {
68 /* setup the policy with the boot policy */
69 if (acm_init_binary_policy((ntohl(pol->secondary_policy_code) << 4) |
70 ntohl(pol->primary_policy_code))) {
71 goto error_free;
72 }
73 acm_active_security_policy =
74 (acm_bin_pol.secondary_policy_code << 4) | acm_bin_pol.primary_policy_code;
75 }
77 /* once acm_active_security_policy is set, it cannot be changed */
78 if ((ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
79 (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code))
80 {
81 printkd("%s: Wrong policy type in boot policy!\n", __func__);
82 goto error_free;
83 }
85 /* get bin_policy lock and rewrite policy (release old one) */
86 write_lock(&acm_bin_pol_rwlock);
88 /* 3. set label reference name */
89 if (acm_set_policy_reference(buf + ntohl(pol->policy_reference_offset),
90 ntohl(pol->primary_buffer_offset) -
91 ntohl(pol->policy_reference_offset)))
92 goto error_lock_free;
94 /* 4. set primary policy data */
95 if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
96 ntohl(pol->secondary_buffer_offset) -
97 ntohl(pol->primary_buffer_offset)))
98 goto error_lock_free;
100 /* 5. set secondary policy data */
101 if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
102 ntohl(pol->len) -
103 ntohl(pol->secondary_buffer_offset)))
104 goto error_lock_free;
106 write_unlock(&acm_bin_pol_rwlock);
107 xfree(policy_buffer);
108 return ACM_OK;
110 error_lock_free:
111 write_unlock(&acm_bin_pol_rwlock);
112 error_free:
113 printk("%s: Error setting policy.\n", __func__);
114 xfree(policy_buffer);
115 return -EFAULT;
116 }
118 int
119 acm_get_policy(void *buf, u32 buf_size)
120 {
121 u8 *policy_buffer;
122 int ret;
123 struct acm_policy_buffer *bin_pol;
125 if (buf_size < sizeof(struct acm_policy_buffer))
126 return -EFAULT;
128 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
129 return -ENOMEM;
131 read_lock(&acm_bin_pol_rwlock);
133 bin_pol = (struct acm_policy_buffer *)policy_buffer;
134 bin_pol->magic = htonl(ACM_MAGIC);
135 bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
136 bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
138 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
139 bin_pol->policy_reference_offset = htonl(ntohl(bin_pol->len));
140 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
141 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
143 ret = acm_dump_policy_reference(policy_buffer + ntohl(bin_pol->policy_reference_offset),
144 buf_size - ntohl(bin_pol->policy_reference_offset));
145 if (ret < 0)
146 goto error_free_unlock;
148 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
149 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
151 ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset),
152 buf_size - ntohl(bin_pol->primary_buffer_offset));
153 if (ret < 0)
154 goto error_free_unlock;
156 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
157 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
159 ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset),
160 buf_size - ntohl(bin_pol->secondary_buffer_offset));
161 if (ret < 0)
162 goto error_free_unlock;
164 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
165 if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
166 goto error_free_unlock;
168 read_unlock(&acm_bin_pol_rwlock);
169 xfree(policy_buffer);
170 return ACM_OK;
172 error_free_unlock:
173 read_unlock(&acm_bin_pol_rwlock);
174 printk("%s: Error getting policy.\n", __func__);
175 xfree(policy_buffer);
176 return -EFAULT;
177 }
179 int
180 acm_dump_statistics(void *buf, u16 buf_size)
181 {
182 /* send stats to user space */
183 u8 *stats_buffer;
184 int len1, len2;
185 struct acm_stats_buffer acm_stats;
187 if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
188 return -ENOMEM;
190 read_lock(&acm_bin_pol_rwlock);
192 len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
193 buf_size - sizeof(struct acm_stats_buffer));
194 if (len1 < 0)
195 goto error_lock_free;
197 len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
198 buf_size - sizeof(struct acm_stats_buffer) - len1);
199 if (len2 < 0)
200 goto error_lock_free;
202 acm_stats.magic = htonl(ACM_MAGIC);
203 acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
204 acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
205 acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
206 acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1);
207 acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
209 memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
211 if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
212 goto error_lock_free;
214 read_unlock(&acm_bin_pol_rwlock);
215 xfree(stats_buffer);
216 return ACM_OK;
218 error_lock_free:
219 read_unlock(&acm_bin_pol_rwlock);
220 xfree(stats_buffer);
221 return -EFAULT;
222 }
225 int
226 acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
227 {
228 /* send stats to user space */
229 u8 *ssid_buffer;
230 int ret;
231 struct acm_ssid_buffer *acm_ssid;
232 if (buf_size < sizeof(struct acm_ssid_buffer))
233 return -EFAULT;
235 if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
236 return -ENOMEM;
238 read_lock(&acm_bin_pol_rwlock);
240 acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
241 acm_ssid->len = sizeof(struct acm_ssid_buffer);
242 acm_ssid->ssidref = ssidref;
243 acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
244 acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
246 acm_ssid->policy_reference_offset = acm_ssid->len;
247 ret = acm_dump_policy_reference(ssid_buffer + acm_ssid->policy_reference_offset,
248 buf_size - acm_ssid->policy_reference_offset);
249 if (ret < 0)
250 goto error_free_unlock;
252 acm_ssid->len += ret;
253 acm_ssid->primary_types_offset = acm_ssid->len;
255 /* ret >= 0 --> ret == max_types */
256 ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
257 ssid_buffer + acm_ssid->primary_types_offset,
258 buf_size - acm_ssid->primary_types_offset);
259 if (ret < 0)
260 goto error_free_unlock;
262 acm_ssid->len += ret;
263 acm_ssid->primary_max_types = ret;
264 acm_ssid->secondary_types_offset = acm_ssid->len;
266 ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
267 ssid_buffer + acm_ssid->secondary_types_offset,
268 buf_size - acm_ssid->secondary_types_offset);
269 if (ret < 0)
270 goto error_free_unlock;
272 acm_ssid->len += ret;
273 acm_ssid->secondary_max_types = ret;
275 if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
276 goto error_free_unlock;
278 read_unlock(&acm_bin_pol_rwlock);
279 xfree(ssid_buffer);
280 return ACM_OK;
282 error_free_unlock:
283 read_unlock(&acm_bin_pol_rwlock);
284 printk("%s: Error getting ssid.\n", __func__);
285 xfree(ssid_buffer);
286 return -ENOMEM;
287 }
289 int
290 acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2,
291 enum acm_hook_type hook)
292 {
293 int ret = ACM_ACCESS_DENIED;
294 switch (hook) {
296 case SHARING:
297 /* SHARING Hook restricts access in STE policy only */
298 ret = acm_sharing(ssidref1, ssidref2);
299 break;
301 default:
302 /* deny */
303 break;
304 }
306 printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
307 __func__, ssidref1, ssidref2,
308 (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
310 return ret;
311 }
313 /*
314 * Local variables:
315 * mode: C
316 * c-set-style: "BSD"
317 * c-basic-offset: 4
318 * tab-width: 4
319 * indent-tabs-mode: nil
320 * End:
321 */