ia64/xen-unstable

view xen/acm/acm_policy.c @ 9706:3c05406f5e0a

In some cases, say for instance for some bizzare reason
the tree was checked out of CVS, which doens't neccessarily
store file permissions, mkbuildtree may not be executable.
So run them explicitly via bash.

Signed-Off-By: Horms <horms@verge.net.au>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 13 11:24:00 2006 +0100 (2006-04-13)
parents cc1d77bba4b0
children 0a5183b3e7bb
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 primary policy data */
89 if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
90 ntohl(pol->secondary_buffer_offset) -
91 ntohl(pol->primary_buffer_offset)))
92 goto error_lock_free;
94 /* 4. set secondary policy data */
95 if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
96 ntohl(pol->len) -
97 ntohl(pol->secondary_buffer_offset)))
98 goto error_lock_free;
100 write_unlock(&acm_bin_pol_rwlock);
101 xfree(policy_buffer);
102 return ACM_OK;
104 error_lock_free:
105 write_unlock(&acm_bin_pol_rwlock);
106 error_free:
107 printk("%s: Error setting policy.\n", __func__);
108 xfree(policy_buffer);
109 return -EFAULT;
110 }
112 int
113 acm_get_policy(void *buf, u32 buf_size)
114 {
115 u8 *policy_buffer;
116 int ret;
117 struct acm_policy_buffer *bin_pol;
119 if (buf_size < sizeof(struct acm_policy_buffer))
120 return -EFAULT;
122 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
123 return -ENOMEM;
125 read_lock(&acm_bin_pol_rwlock);
127 bin_pol = (struct acm_policy_buffer *)policy_buffer;
128 bin_pol->magic = htonl(ACM_MAGIC);
129 bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
130 bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
132 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
133 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
134 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
136 ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset),
137 buf_size - ntohl(bin_pol->primary_buffer_offset));
138 if (ret < 0)
139 goto error_free_unlock;
141 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
142 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
144 ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset),
145 buf_size - ntohl(bin_pol->secondary_buffer_offset));
146 if (ret < 0)
147 goto error_free_unlock;
149 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
150 if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
151 goto error_free_unlock;
153 read_unlock(&acm_bin_pol_rwlock);
154 xfree(policy_buffer);
155 return ACM_OK;
157 error_free_unlock:
158 read_unlock(&acm_bin_pol_rwlock);
159 printk("%s: Error getting policy.\n", __func__);
160 xfree(policy_buffer);
161 return -EFAULT;
162 }
164 int
165 acm_dump_statistics(void *buf, u16 buf_size)
166 {
167 /* send stats to user space */
168 u8 *stats_buffer;
169 int len1, len2;
170 struct acm_stats_buffer acm_stats;
172 if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
173 return -ENOMEM;
175 read_lock(&acm_bin_pol_rwlock);
177 len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
178 buf_size - sizeof(struct acm_stats_buffer));
179 if (len1 < 0)
180 goto error_lock_free;
182 len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
183 buf_size - sizeof(struct acm_stats_buffer) - len1);
184 if (len2 < 0)
185 goto error_lock_free;
187 acm_stats.magic = htonl(ACM_MAGIC);
188 acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
189 acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
190 acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
191 acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1);
192 acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
194 memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
196 if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
197 goto error_lock_free;
199 read_unlock(&acm_bin_pol_rwlock);
200 xfree(stats_buffer);
201 return ACM_OK;
203 error_lock_free:
204 read_unlock(&acm_bin_pol_rwlock);
205 xfree(stats_buffer);
206 return -EFAULT;
207 }
210 int
211 acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
212 {
213 /* send stats to user space */
214 u8 *ssid_buffer;
215 int ret;
216 struct acm_ssid_buffer *acm_ssid;
217 if (buf_size < sizeof(struct acm_ssid_buffer))
218 return -EFAULT;
220 if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
221 return -ENOMEM;
223 read_lock(&acm_bin_pol_rwlock);
225 acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
226 acm_ssid->len = sizeof(struct acm_ssid_buffer);
227 acm_ssid->ssidref = ssidref;
228 acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
229 acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
230 acm_ssid->primary_types_offset = acm_ssid->len;
232 /* ret >= 0 --> ret == max_types */
233 ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
234 ssid_buffer + acm_ssid->primary_types_offset,
235 buf_size - acm_ssid->primary_types_offset);
236 if (ret < 0)
237 goto error_free_unlock;
239 acm_ssid->len += ret;
240 acm_ssid->primary_max_types = ret;
241 acm_ssid->secondary_types_offset = acm_ssid->len;
243 ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
244 ssid_buffer + acm_ssid->secondary_types_offset,
245 buf_size - acm_ssid->secondary_types_offset);
246 if (ret < 0)
247 goto error_free_unlock;
249 acm_ssid->len += ret;
250 acm_ssid->secondary_max_types = ret;
252 if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
253 goto error_free_unlock;
255 read_unlock(&acm_bin_pol_rwlock);
256 xfree(ssid_buffer);
257 return ACM_OK;
259 error_free_unlock:
260 read_unlock(&acm_bin_pol_rwlock);
261 printk("%s: Error getting ssid.\n", __func__);
262 xfree(ssid_buffer);
263 return -ENOMEM;
264 }
266 int
267 acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2,
268 enum acm_hook_type hook)
269 {
270 int ret = ACM_ACCESS_DENIED;
271 switch (hook) {
273 case SHARING:
274 /* SHARING Hook restricts access in STE policy only */
275 ret = acm_sharing(ssidref1, ssidref2);
276 break;
278 default:
279 /* deny */
280 break;
281 }
283 printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
284 __func__, ssidref1, ssidref2,
285 (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
287 return ret;
288 }
290 /*
291 * Local variables:
292 * mode: C
293 * c-set-style: "BSD"
294 * c-basic-offset: 4
295 * tab-width: 4
296 * indent-tabs-mode: nil
297 * End:
298 */