#define PULL_CACHE_SIZE 8192
uint8_t pull_buffer[PULL_CACHE_SIZE];
+
int acm_domain_getpolicy(int xc_handle)
{
struct acm_getpolicy getpolicy;
memset(pull_buffer, 0x00, sizeof(pull_buffer));
getpolicy.interface_version = ACM_INTERFACE_VERSION;
- getpolicy.pullcache = (void *) pull_buffer;
+ set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
getpolicy.pullcache_size = sizeof(pull_buffer);
ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
/* dump it and then push it down into xen/acm */
acm_dump_policy_buffer(buffer, len);
setpolicy.interface_version = ACM_INTERFACE_VERSION;
- setpolicy.pushcache = (void *) buffer;
+ set_xen_guest_handle(setpolicy.pushcache, buffer);
setpolicy.pushcache_size = len;
ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy));
memset(stats_buffer, 0x00, sizeof(stats_buffer));
dumpstats.interface_version = ACM_INTERFACE_VERSION;
- dumpstats.pullcache = (void *) stats_buffer;
+ set_xen_guest_handle(dumpstats.pullcache, stats_buffer);
dumpstats.pullcache_size = sizeof(stats_buffer);
ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
pol = (struct acm_policy_buffer *)_policy_start;
if (ntohl(pol->magic) == ACM_MAGIC)
{
- rc = acm_set_policy((void *)_policy_start,
- (u32)_policy_len,
- 0);
+ rc = do_acm_set_policy((void *)_policy_start,
+ (u32)_policy_len);
if (rc == ACM_OK)
{
printkd("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start);
#include <xen/lib.h>
#include <xen/delay.h>
#include <xen/sched.h>
+#include <xen/guest_access.h>
#include <acm/acm_core.h>
#include <public/acm_ops.h>
#include <acm/acm_hooks.h>
#include <acm/acm_endian.h>
int
-acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer)
+acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
{
u8 *policy_buffer = NULL;
- struct acm_policy_buffer *pol;
+ int ret = -EFAULT;
if (buf_size < sizeof(struct acm_policy_buffer))
return -EFAULT;
- /* 1. copy buffer from domain */
+ /* copy buffer from guest domain */
if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
return -ENOMEM;
- if (isuserbuffer) {
- if (copy_from_guest(policy_buffer, buf, buf_size))
- {
- printk("%s: Error copying!\n",__func__);
- goto error_free;
- }
- } else
- memcpy(policy_buffer, buf, buf_size);
+ if (copy_from_guest(policy_buffer, buf, buf_size))
+ {
+ printk("%s: Error copying!\n",__func__);
+ goto error_free;
+ }
+ ret = do_acm_set_policy(policy_buffer, buf_size);
+
+ error_free:
+ xfree(policy_buffer);
+ return ret;
+}
- /* 2. some sanity checking */
- pol = (struct acm_policy_buffer *)policy_buffer;
+int
+do_acm_set_policy(void *buf, u32 buf_size)
+{
+ struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+ /* some sanity checking */
if ((ntohl(pol->magic) != ACM_MAGIC) ||
(buf_size != ntohl(pol->len)) ||
(ntohl(pol->policy_version) != ACM_POLICY_VERSION))
/* get bin_policy lock and rewrite policy (release old one) */
write_lock(&acm_bin_pol_rwlock);
- /* 3. set label reference name */
+ /* set label reference name */
if (acm_set_policy_reference(buf + ntohl(pol->policy_reference_offset),
ntohl(pol->primary_buffer_offset) -
ntohl(pol->policy_reference_offset)))
goto error_lock_free;
- /* 4. set primary policy data */
+ /* set primary policy data */
if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset),
ntohl(pol->secondary_buffer_offset) -
ntohl(pol->primary_buffer_offset)))
goto error_lock_free;
- /* 5. set secondary policy data */
+ /* set secondary policy data */
if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset),
ntohl(pol->len) -
ntohl(pol->secondary_buffer_offset)))
goto error_lock_free;
write_unlock(&acm_bin_pol_rwlock);
- xfree(policy_buffer);
return ACM_OK;
error_lock_free:
write_unlock(&acm_bin_pol_rwlock);
error_free:
printk("%s: Error setting policy.\n", __func__);
- xfree(policy_buffer);
return -EFAULT;
}
return -EACCES;
rc = acm_set_policy(setpolicy.pushcache,
- setpolicy.pushcache_size, 1);
+ setpolicy.pushcache_size);
break;
}
spin_unlock(&dom0_lock);
if (!ret)
- acm_post_dom0_op(op, ssid);
+ acm_post_dom0_op(op, &ssid);
else
- acm_fail_dom0_op(op, ssid);
+ acm_fail_dom0_op(op, &ssid);
return ret;
}
int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
int acm_init_binary_policy(u32 policy_code);
-int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer);
-int acm_get_policy(void *buf, u32 buf_size);
-int acm_dump_statistics(void *buf, u16 buf_size);
-int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
+int acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
+int do_acm_set_policy(void *buf, u32 buf_size);
+int acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size);
+int acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size);
+int acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size);
int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook);
int acm_set_policy_reference(u8 * buf, u32 buf_size);
int acm_dump_policy_reference(u8 *buf, u32 buf_size);
op->u.createdomain.domain, op->u.createdomain.ssidref);
break;
case DOM0_DESTROYDOMAIN:
- acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
+ if (*ssid == NULL) {
+ printkd("%s: ERROR. SSID unset.\n",
+ __func__);
+ break;
+ }
+ acm_post_domain_destroy(*ssid, op->u.destroydomain.domain);
/* free security ssid for the destroyed domain (also if null policy */
acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
*ssid = NULL;
}
}
-static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid)
+static inline void acm_fail_dom0_op(struct dom0_op *op, void **ssid)
{
switch(op->cmd) {
case DOM0_CREATEDOMAIN:
acm_fail_domain_create(
current->domain->ssid, op->u.createdomain.ssidref);
break;
+ case DOM0_DESTROYDOMAIN:
+ /* we don't handle domain destroy failure but at least free the ssid */
+ if (*ssid == NULL) {
+ printkd("%s: ERROR. SSID unset.\n",
+ __func__);
+ break;
+ }
+ acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
+ *ssid = NULL;
}
}