ia64/xen-unstable

view xen/acm/acm_policy.c @ 10718:3cdb93867f81

Domain ID/index mapping in xenmon.

This patch addresses the problem of xenbaked/xenmon not dealing with
large domain ID's. Xen Domain ID's increase monotonically as domains
are created; The ID's are not (often) recycled. Xenbaked was using the
domain
ID's as indices to arrays of data, and this scheme blows up as soon as
a domain ID exceeds the array size. Code has been changed in xenbaked
and xenmon to isolate domain id's from array indices, so everything is
indirect. Users should not notice any difference in behavior.

From: Rob Gardner <rob.gardner@hp.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Jul 10 16:09:20 2006 +0100 (2006-07-10)
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 */