ia64/xen-unstable

view xen/acm/acm_policy.c @ 11624:f5fd563bcc84

[XEN] Small clean up.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Sep 25 17:45:28 2006 +0100 (2006-09-25)
parents 21e6625a6c01
children 699656fb1d0b
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 <xen/guest_access.h>
30 #include <acm/acm_core.h>
31 #include <public/acm_ops.h>
32 #include <acm/acm_hooks.h>
33 #include <acm/acm_endian.h>
35 int
36 acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
37 {
38 u8 *policy_buffer = NULL;
39 int ret = -EFAULT;
41 if (buf_size < sizeof(struct acm_policy_buffer))
42 return -EFAULT;
44 /* copy buffer from guest domain */
45 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
46 return -ENOMEM;
48 if (copy_from_guest(policy_buffer, buf, buf_size))
49 {
50 printk("%s: Error copying!\n",__func__);
51 goto error_free;
52 }
53 ret = do_acm_set_policy(policy_buffer, buf_size);
55 error_free:
56 xfree(policy_buffer);
57 return ret;
58 }
61 int
62 do_acm_set_policy(void *buf, u32 buf_size)
63 {
64 struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
65 /* some sanity checking */
66 if ((ntohl(pol->magic) != ACM_MAGIC) ||
67 (buf_size != ntohl(pol->len)) ||
68 (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
69 {
70 printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
71 goto error_free;
72 }
74 if (acm_active_security_policy == ACM_POLICY_UNDEFINED) {
75 /* setup the policy with the boot policy */
76 if (acm_init_binary_policy((ntohl(pol->secondary_policy_code) << 4) |
77 ntohl(pol->primary_policy_code))) {
78 goto error_free;
79 }
80 acm_active_security_policy =
81 (acm_bin_pol.secondary_policy_code << 4) | acm_bin_pol.primary_policy_code;
82 }
84 /* once acm_active_security_policy is set, it cannot be changed */
85 if ((ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
86 (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code))
87 {
88 printkd("%s: Wrong policy type in boot policy!\n", __func__);
89 goto error_free;
90 }
92 /* get bin_policy lock and rewrite policy (release old one) */
93 write_lock(&acm_bin_pol_rwlock);
95 /* set label reference name */
96 if (acm_set_policy_reference(buf + ntohl(pol->policy_reference_offset),
97 ntohl(pol->primary_buffer_offset) -
98 ntohl(pol->policy_reference_offset)))
99 goto error_lock_free;
101 /* set primary policy data */
102 if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
103 ntohl(pol->secondary_buffer_offset) -
104 ntohl(pol->primary_buffer_offset)))
105 goto error_lock_free;
107 /* set secondary policy data */
108 if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
109 ntohl(pol->len) -
110 ntohl(pol->secondary_buffer_offset)))
111 goto error_lock_free;
113 write_unlock(&acm_bin_pol_rwlock);
114 return ACM_OK;
116 error_lock_free:
117 write_unlock(&acm_bin_pol_rwlock);
118 error_free:
119 printk("%s: Error setting policy.\n", __func__);
120 return -EFAULT;
121 }
123 int
124 acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
125 {
126 u8 *policy_buffer;
127 int ret;
128 struct acm_policy_buffer *bin_pol;
130 if (buf_size < sizeof(struct acm_policy_buffer))
131 return -EFAULT;
133 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
134 return -ENOMEM;
136 read_lock(&acm_bin_pol_rwlock);
138 bin_pol = (struct acm_policy_buffer *)policy_buffer;
139 bin_pol->magic = htonl(ACM_MAGIC);
140 bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
141 bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
143 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
144 bin_pol->policy_reference_offset = htonl(ntohl(bin_pol->len));
145 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
146 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
148 ret = acm_dump_policy_reference(policy_buffer + ntohl(bin_pol->policy_reference_offset),
149 buf_size - ntohl(bin_pol->policy_reference_offset));
150 if (ret < 0)
151 goto error_free_unlock;
153 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
154 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
156 ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset),
157 buf_size - ntohl(bin_pol->primary_buffer_offset));
158 if (ret < 0)
159 goto error_free_unlock;
161 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
162 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
164 ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset),
165 buf_size - ntohl(bin_pol->secondary_buffer_offset));
166 if (ret < 0)
167 goto error_free_unlock;
169 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
170 if (copy_to_guest(buf, policy_buffer, ntohl(bin_pol->len)))
171 goto error_free_unlock;
173 read_unlock(&acm_bin_pol_rwlock);
174 xfree(policy_buffer);
175 return ACM_OK;
177 error_free_unlock:
178 read_unlock(&acm_bin_pol_rwlock);
179 printk("%s: Error getting policy.\n", __func__);
180 xfree(policy_buffer);
181 return -EFAULT;
182 }
184 int
185 acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size)
186 {
187 /* send stats to user space */
188 u8 *stats_buffer;
189 int len1, len2;
190 struct acm_stats_buffer acm_stats;
192 if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
193 return -ENOMEM;
195 read_lock(&acm_bin_pol_rwlock);
197 len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
198 buf_size - sizeof(struct acm_stats_buffer));
199 if (len1 < 0)
200 goto error_lock_free;
202 len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
203 buf_size - sizeof(struct acm_stats_buffer) - len1);
204 if (len2 < 0)
205 goto error_lock_free;
207 acm_stats.magic = htonl(ACM_MAGIC);
208 acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
209 acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
210 acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
211 acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1);
212 acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
214 memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
216 if (copy_to_guest(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
217 goto error_lock_free;
219 read_unlock(&acm_bin_pol_rwlock);
220 xfree(stats_buffer);
221 return ACM_OK;
223 error_lock_free:
224 read_unlock(&acm_bin_pol_rwlock);
225 xfree(stats_buffer);
226 return -EFAULT;
227 }
230 int
231 acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size)
232 {
233 /* send stats to user space */
234 u8 *ssid_buffer;
235 int ret;
236 struct acm_ssid_buffer *acm_ssid;
237 if (buf_size < sizeof(struct acm_ssid_buffer))
238 return -EFAULT;
240 if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
241 return -ENOMEM;
243 read_lock(&acm_bin_pol_rwlock);
245 acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
246 acm_ssid->len = sizeof(struct acm_ssid_buffer);
247 acm_ssid->ssidref = ssidref;
248 acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
249 acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
251 acm_ssid->policy_reference_offset = acm_ssid->len;
252 ret = acm_dump_policy_reference(ssid_buffer + acm_ssid->policy_reference_offset,
253 buf_size - acm_ssid->policy_reference_offset);
254 if (ret < 0)
255 goto error_free_unlock;
257 acm_ssid->len += ret;
258 acm_ssid->primary_types_offset = acm_ssid->len;
260 /* ret >= 0 --> ret == max_types */
261 ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
262 ssid_buffer + acm_ssid->primary_types_offset,
263 buf_size - acm_ssid->primary_types_offset);
264 if (ret < 0)
265 goto error_free_unlock;
267 acm_ssid->len += ret;
268 acm_ssid->primary_max_types = ret;
269 acm_ssid->secondary_types_offset = acm_ssid->len;
271 ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
272 ssid_buffer + acm_ssid->secondary_types_offset,
273 buf_size - acm_ssid->secondary_types_offset);
274 if (ret < 0)
275 goto error_free_unlock;
277 acm_ssid->len += ret;
278 acm_ssid->secondary_max_types = ret;
280 if (copy_to_guest(buf, ssid_buffer, acm_ssid->len))
281 goto error_free_unlock;
283 read_unlock(&acm_bin_pol_rwlock);
284 xfree(ssid_buffer);
285 return ACM_OK;
287 error_free_unlock:
288 read_unlock(&acm_bin_pol_rwlock);
289 printk("%s: Error getting ssid.\n", __func__);
290 xfree(ssid_buffer);
291 return -ENOMEM;
292 }
294 int
295 acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook)
296 {
297 int ret = ACM_ACCESS_DENIED;
298 switch (hook) {
300 case ACMHOOK_sharing:
301 /* Sharing hook restricts access in STE policy only */
302 ret = acm_sharing(ssidref1, ssidref2);
303 break;
305 default:
306 /* deny */
307 break;
308 }
310 printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
311 __func__, ssidref1, ssidref2,
312 (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
314 return ret;
315 }
317 /*
318 * Local variables:
319 * mode: C
320 * c-set-style: "BSD"
321 * c-basic-offset: 4
322 * tab-width: 4
323 * indent-tabs-mode: nil
324 * End:
325 */