ia64/xen-unstable

annotate xen/acm/acm_policy.c @ 9738:c4eead8a925b

Only BSP can really do clear_all_shadow_status.
This fixes SMP IA32 VMX guest booting on IA32 xen.

Signed-off-by: Xin Li <xin.b.li@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Apr 16 15:41:31 2006 +0100 (2006-04-16)
parents cc1d77bba4b0
children 0a5183b3e7bb
rev   line source
smh22@5514 1 /****************************************************************
smh22@5514 2 * acm_policy.c
smh22@5514 3 *
smh22@5514 4 * Copyright (C) 2005 IBM Corporation
smh22@5514 5 *
smh22@5514 6 * Author:
smh22@5514 7 * Reiner Sailer <sailer@watson.ibm.com>
smh22@5514 8 *
smh22@5957 9 * Contributors:
smh22@5514 10 * Stefan Berger <stefanb@watson.ibm.com>
smh22@5514 11 *
smh22@5514 12 * This program is free software; you can redistribute it and/or
smh22@5514 13 * modify it under the terms of the GNU General Public License as
smh22@5514 14 * published by the Free Software Foundation, version 2 of the
smh22@5514 15 * License.
smh22@5514 16 *
smh22@5514 17 * sHype access control policy management for Xen.
smh22@5514 18 * This interface allows policy tools in authorized
smh22@5514 19 * domains to interact with the Xen access control module
smh22@5514 20 *
smh22@5514 21 */
smh22@5514 22
smh22@5514 23 #include <xen/config.h>
smh22@5514 24 #include <xen/errno.h>
smh22@5514 25 #include <xen/types.h>
smh22@5514 26 #include <xen/lib.h>
smh22@5514 27 #include <xen/delay.h>
smh22@5514 28 #include <xen/sched.h>
kaf24@6597 29 #include <acm/acm_core.h>
smh22@5957 30 #include <public/acm_ops.h>
smh22@5514 31 #include <acm/acm_hooks.h>
smh22@5514 32 #include <acm/acm_endian.h>
smh22@5514 33
smh22@5514 34 int
kaf24@7457 35 acm_set_policy(void *buf, u32 buf_size, int isuserbuffer)
smh22@5514 36 {
kaf24@7457 37 u8 *policy_buffer = NULL;
kaf24@7457 38 struct acm_policy_buffer *pol;
kaf24@7457 39
kaf24@6597 40 if (buf_size < sizeof(struct acm_policy_buffer))
kaf24@7457 41 return -EFAULT;
smh22@5957 42
kaf24@7457 43 /* 1. copy buffer from domain */
kaf24@7457 44 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
kaf24@7457 45 return -ENOMEM;
kaf24@6597 46
kaf24@7457 47 if (isuserbuffer) {
kaf24@7457 48 if (copy_from_user(policy_buffer, buf, buf_size))
kaf24@6597 49 {
kaf24@7457 50 printk("%s: Error copying!\n",__func__);
kaf24@7457 51 goto error_free;
kaf24@7457 52 }
kaf24@7457 53 } else
kaf24@7457 54 memcpy(policy_buffer, buf, buf_size);
smh22@5957 55
kaf24@7457 56 /* 2. some sanity checking */
kaf24@7457 57 pol = (struct acm_policy_buffer *)policy_buffer;
smh22@5514 58
kaf24@7935 59 if ((ntohl(pol->magic) != ACM_MAGIC) ||
kaf24@7935 60 (buf_size != ntohl(pol->len)) ||
kaf24@7935 61 (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
kaf24@7935 62 {
kaf24@7935 63 printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
kaf24@7935 64 goto error_free;
kaf24@7935 65 }
kaf24@7935 66
kaf24@7935 67 if (acm_active_security_policy == ACM_POLICY_UNDEFINED) {
kaf24@7935 68 /* setup the policy with the boot policy */
kaf24@7935 69 if (acm_init_binary_policy((ntohl(pol->secondary_policy_code) << 4) |
kaf24@7935 70 ntohl(pol->primary_policy_code))) {
kaf24@7935 71 goto error_free;
kaf24@7935 72 }
kaf24@7935 73 acm_active_security_policy =
kaf24@7935 74 (acm_bin_pol.secondary_policy_code << 4) | acm_bin_pol.primary_policy_code;
kaf24@7935 75 }
kaf24@7935 76
kaf24@7935 77 /* once acm_active_security_policy is set, it cannot be changed */
kaf24@7935 78 if ((ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
kaf24@7457 79 (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code))
kaf24@6597 80 {
kaf24@7935 81 printkd("%s: Wrong policy type in boot policy!\n", __func__);
kaf24@7457 82 goto error_free;
kaf24@7457 83 }
smh22@5514 84
kaf24@7457 85 /* get bin_policy lock and rewrite policy (release old one) */
kaf24@7457 86 write_lock(&acm_bin_pol_rwlock);
smh22@5514 87
kaf24@7457 88 /* 3. set primary policy data */
kaf24@7457 89 if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
kaf24@7457 90 ntohl(pol->secondary_buffer_offset) -
kaf24@7457 91 ntohl(pol->primary_buffer_offset)))
kaf24@7457 92 goto error_lock_free;
kaf24@6597 93
kaf24@7457 94 /* 4. set secondary policy data */
kaf24@7457 95 if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
kaf24@7457 96 ntohl(pol->len) -
kaf24@7457 97 ntohl(pol->secondary_buffer_offset)))
kaf24@7457 98 goto error_lock_free;
kaf24@6597 99
kaf24@7457 100 write_unlock(&acm_bin_pol_rwlock);
kaf24@7457 101 xfree(policy_buffer);
kaf24@7457 102 return ACM_OK;
smh22@5514 103
smh22@5514 104 error_lock_free:
kaf24@7457 105 write_unlock(&acm_bin_pol_rwlock);
smh22@5514 106 error_free:
kaf24@7457 107 printk("%s: Error setting policy.\n", __func__);
kaf24@6597 108 xfree(policy_buffer);
kaf24@7457 109 return -EFAULT;
smh22@5514 110 }
smh22@5514 111
smh22@5514 112 int
kaf24@7457 113 acm_get_policy(void *buf, u32 buf_size)
kaf24@7457 114 {
kaf24@7457 115 u8 *policy_buffer;
kaf24@7457 116 int ret;
kaf24@7457 117 struct acm_policy_buffer *bin_pol;
kaf24@7457 118
kaf24@6597 119 if (buf_size < sizeof(struct acm_policy_buffer))
kaf24@7457 120 return -EFAULT;
kaf24@6597 121
kaf24@7457 122 if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
kaf24@7457 123 return -ENOMEM;
smh22@5514 124
kaf24@7457 125 read_lock(&acm_bin_pol_rwlock);
kaf24@6597 126
kaf24@7457 127 bin_pol = (struct acm_policy_buffer *)policy_buffer;
kaf24@7457 128 bin_pol->magic = htonl(ACM_MAGIC);
kaf24@7457 129 bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
kaf24@7457 130 bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
smh22@5514 131
kaf24@7457 132 bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
kaf24@7457 133 bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
kaf24@7457 134 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
smh22@5514 135
kaf24@7457 136 ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset),
kaf24@7457 137 buf_size - ntohl(bin_pol->primary_buffer_offset));
kaf24@7457 138 if (ret < 0)
kaf24@7457 139 goto error_free_unlock;
kaf24@6597 140
kaf24@7457 141 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
kaf24@7457 142 bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
smh22@5514 143
kaf24@7457 144 ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset),
kaf24@7457 145 buf_size - ntohl(bin_pol->secondary_buffer_offset));
kaf24@7457 146 if (ret < 0)
kaf24@7457 147 goto error_free_unlock;
kaf24@6597 148
kaf24@7457 149 bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
kaf24@7457 150 if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
kaf24@7457 151 goto error_free_unlock;
kaf24@6597 152
kaf24@7457 153 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 154 xfree(policy_buffer);
kaf24@7457 155 return ACM_OK;
kaf24@6597 156
kaf24@6597 157 error_free_unlock:
kaf24@7457 158 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 159 printk("%s: Error getting policy.\n", __func__);
kaf24@7457 160 xfree(policy_buffer);
kaf24@7457 161 return -EFAULT;
smh22@5514 162 }
smh22@5514 163
smh22@5514 164 int
smh22@5514 165 acm_dump_statistics(void *buf, u16 buf_size)
kaf24@7457 166 {
smh22@5514 167 /* send stats to user space */
kaf24@7457 168 u8 *stats_buffer;
kaf24@7457 169 int len1, len2;
kaf24@7457 170 struct acm_stats_buffer acm_stats;
smh22@5514 171
kaf24@7457 172 if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
kaf24@7457 173 return -ENOMEM;
smh22@5514 174
kaf24@7457 175 read_lock(&acm_bin_pol_rwlock);
smh22@5514 176
kaf24@7457 177 len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
kaf24@7457 178 buf_size - sizeof(struct acm_stats_buffer));
kaf24@7457 179 if (len1 < 0)
kaf24@7457 180 goto error_lock_free;
kaf24@7457 181
kaf24@7457 182 len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
kaf24@7457 183 buf_size - sizeof(struct acm_stats_buffer) - len1);
kaf24@7457 184 if (len2 < 0)
kaf24@7457 185 goto error_lock_free;
smh22@5514 186
kaf24@7457 187 acm_stats.magic = htonl(ACM_MAGIC);
kaf24@7457 188 acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
kaf24@7457 189 acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
kaf24@7457 190 acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
kaf24@7457 191 acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1);
kaf24@7457 192 acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
smh22@5514 193
kaf24@7457 194 memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
smh22@5514 195
kaf24@7457 196 if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
kaf24@7457 197 goto error_lock_free;
kaf24@7457 198
kaf24@7457 199 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 200 xfree(stats_buffer);
kaf24@7457 201 return ACM_OK;
smh22@5514 202
smh22@5514 203 error_lock_free:
kaf24@7457 204 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 205 xfree(stats_buffer);
kaf24@7457 206 return -EFAULT;
smh22@5514 207 }
smh22@5514 208
kaf24@6597 209
kaf24@6597 210 int
kaf24@6597 211 acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
kaf24@6597 212 {
kaf24@6597 213 /* send stats to user space */
kaf24@7457 214 u8 *ssid_buffer;
kaf24@7457 215 int ret;
kaf24@7457 216 struct acm_ssid_buffer *acm_ssid;
kaf24@7457 217 if (buf_size < sizeof(struct acm_ssid_buffer))
kaf24@7457 218 return -EFAULT;
kaf24@6597 219
kaf24@7457 220 if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
kaf24@7457 221 return -ENOMEM;
kaf24@6597 222
kaf24@7457 223 read_lock(&acm_bin_pol_rwlock);
kaf24@6597 224
kaf24@7457 225 acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
kaf24@7457 226 acm_ssid->len = sizeof(struct acm_ssid_buffer);
kaf24@7457 227 acm_ssid->ssidref = ssidref;
kaf24@7457 228 acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
kaf24@7457 229 acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
kaf24@7457 230 acm_ssid->primary_types_offset = acm_ssid->len;
kaf24@6597 231
kaf24@7457 232 /* ret >= 0 --> ret == max_types */
kaf24@7457 233 ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
kaf24@7457 234 ssid_buffer + acm_ssid->primary_types_offset,
kaf24@7457 235 buf_size - acm_ssid->primary_types_offset);
kaf24@7457 236 if (ret < 0)
kaf24@7457 237 goto error_free_unlock;
kaf24@6597 238
kaf24@7457 239 acm_ssid->len += ret;
kaf24@7457 240 acm_ssid->primary_max_types = ret;
kaf24@7457 241 acm_ssid->secondary_types_offset = acm_ssid->len;
kaf24@6597 242
kaf24@7457 243 ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
kaf24@7457 244 ssid_buffer + acm_ssid->secondary_types_offset,
kaf24@7457 245 buf_size - acm_ssid->secondary_types_offset);
kaf24@7457 246 if (ret < 0)
kaf24@7457 247 goto error_free_unlock;
kaf24@6597 248
kaf24@7457 249 acm_ssid->len += ret;
kaf24@7457 250 acm_ssid->secondary_max_types = ret;
kaf24@6597 251
kaf24@7457 252 if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
kaf24@7457 253 goto error_free_unlock;
kaf24@6597 254
kaf24@7457 255 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 256 xfree(ssid_buffer);
kaf24@7457 257 return ACM_OK;
kaf24@6597 258
kaf24@6597 259 error_free_unlock:
kaf24@7457 260 read_unlock(&acm_bin_pol_rwlock);
kaf24@7457 261 printk("%s: Error getting ssid.\n", __func__);
kaf24@7457 262 xfree(ssid_buffer);
kaf24@7457 263 return -ENOMEM;
kaf24@6597 264 }
kaf24@6597 265
kaf24@7457 266 int
kaf24@7457 267 acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2,
kaf24@7457 268 enum acm_hook_type hook)
kaf24@7457 269 {
kaf24@7457 270 int ret = ACM_ACCESS_DENIED;
kaf24@7457 271 switch (hook) {
kaf24@7457 272
kaf24@7457 273 case SHARING:
kaf24@7457 274 /* SHARING Hook restricts access in STE policy only */
kaf24@7457 275 ret = acm_sharing(ssidref1, ssidref2);
kaf24@7457 276 break;
kaf24@7457 277
kaf24@7457 278 default:
kaf24@7457 279 /* deny */
kaf24@7457 280 break;
kaf24@7457 281 }
kaf24@7457 282
kaf24@7457 283 printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
kaf24@7457 284 __func__, ssidref1, ssidref2,
kaf24@7457 285 (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
kaf24@7457 286
kaf24@7457 287 return ret;
kaf24@7457 288 }
kaf24@7457 289
kaf24@7457 290 /*
kaf24@7457 291 * Local variables:
kaf24@7457 292 * mode: C
kaf24@7457 293 * c-set-style: "BSD"
kaf24@7457 294 * c-basic-offset: 4
kaf24@7457 295 * tab-width: 4
kaf24@7457 296 * indent-tabs-mode: nil
kaf24@7457 297 * End:
kaf24@7457 298 */