ia64/xen-unstable

view xen/acm/acm_policy.c @ 8723:61e7afb7344b

The memset in init_switch_stack is overwriting the processor stack.
We need to avoid manipulating the switch stack area of the currently
running cpu. Original patch by Kevin Tian.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Feb 01 00:56:19 2006 +0100 (2006-02-01)
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 */