mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
This patch adds support in the hypervisor for the policy name attribute
introduced into security policies. It also fixes a minor problem related to handling unsupported boot policies. Signed-off by: Reiner Sailer <sailer@us.ibm.com>
This commit is contained in:
1 parent
c462e5c2f0
commit
87d52008e4
5 files changed
+82
-18
No files matched your search
+41
-8
@@ -70,16 +70,45 @@ acm_set_endian(void)
|
||||
u32 test = 1;
|
||||
if (*((u8 *)&test) == 1)
|
||||
{
|
||||
printk("ACM module running in LITTLE ENDIAN.\n");
|
||||
printkd("ACM module running in LITTLE ENDIAN.\n");
|
||||
little_endian = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("ACM module running in BIG ENDIAN.\n");
|
||||
printkd("ACM module running in BIG ENDIAN.\n");
|
||||
little_endian = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
acm_set_policy_reference(u8 * buf, u32 buf_size)
|
||||
{
|
||||
struct acm_policy_reference_buffer *pr = (struct acm_policy_reference_buffer *)buf;
|
||||
acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, ntohl(pr->len));
|
||||
|
||||
if (!acm_bin_pol.policy_reference_name)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(acm_bin_pol.policy_reference_name, (char *)(buf + sizeof(struct acm_policy_reference_buffer)));
|
||||
printk("%s: Activating policy %s\n", __func__, acm_bin_pol.policy_reference_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
acm_dump_policy_reference(u8 *buf, u32 buf_size)
|
||||
{
|
||||
struct acm_policy_reference_buffer *pr_buf = (struct acm_policy_reference_buffer *)buf;
|
||||
int ret = sizeof(struct acm_policy_reference_buffer) + strlen(acm_bin_pol.policy_reference_name) + 1;
|
||||
|
||||
if (buf_size < ret)
|
||||
return -EINVAL;
|
||||
|
||||
pr_buf->len = htonl(strlen(acm_bin_pol.policy_reference_name) + 1); /* including stringend '\0' */
|
||||
strcpy((char *)(buf + sizeof(struct acm_policy_reference_buffer)),
|
||||
acm_bin_pol.policy_reference_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
acm_init_binary_policy(u32 policy_code)
|
||||
{
|
||||
@@ -198,7 +227,7 @@ acm_setup(unsigned int *initrdidx,
|
||||
0);
|
||||
if (rc == ACM_OK)
|
||||
{
|
||||
printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start);
|
||||
printkd("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start);
|
||||
if (i == 1)
|
||||
{
|
||||
if (mbi->mods_count > 2)
|
||||
@@ -218,6 +247,8 @@ acm_setup(unsigned int *initrdidx,
|
||||
else
|
||||
{
|
||||
printk("Invalid policy. %d.th module line.\n", i+1);
|
||||
/* load default policy later */
|
||||
acm_active_security_policy = ACM_POLICY_UNDEFINED;
|
||||
}
|
||||
} /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */
|
||||
}
|
||||
@@ -239,10 +270,8 @@ acm_init(unsigned int *initrdidx,
|
||||
|
||||
if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
|
||||
{
|
||||
printk("%s: Boot-Policy. Enforcing %s: Primary %s, Secondary %s.\n", __func__,
|
||||
ACM_POLICY_NAME(acm_active_security_policy),
|
||||
ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
|
||||
ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
|
||||
printk("%s: Enforcing %s boot policy.\n", __func__,
|
||||
ACM_POLICY_NAME(acm_active_security_policy));
|
||||
goto out;
|
||||
}
|
||||
/* else continue with the minimal hardcoded default startup policy */
|
||||
@@ -254,6 +283,10 @@ acm_init(unsigned int *initrdidx,
|
||||
goto out;
|
||||
}
|
||||
acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY;
|
||||
if (acm_active_security_policy != ACM_NULL_POLICY)
|
||||
acm_bin_pol.policy_reference_name = "DEFAULT";
|
||||
else
|
||||
acm_bin_pol.policy_reference_name = "NULL";
|
||||
|
||||
out:
|
||||
if (ret != ACM_OK)
|
||||
@@ -314,7 +347,7 @@ acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
|
||||
put_domain(subj);
|
||||
return ACM_INIT_SSID_ERROR;
|
||||
}
|
||||
printk("%s: assigned domain %x the ssidref=%x.\n",
|
||||
printkd("%s: assigned domain %x the ssidref=%x.\n",
|
||||
__func__, id, ssid->ssidref);
|
||||
put_domain(subj);
|
||||
return ACM_OK;
|
||||
|
||||
+25
-2
@@ -85,13 +85,19 @@ acm_set_policy(void *buf, u32 buf_size, int isuserbuffer)
|
||||
/* get bin_policy lock and rewrite policy (release old one) */
|
||||
write_lock(&acm_bin_pol_rwlock);
|
||||
|
||||
/* 3. set primary policy data */
|
||||
/* 3. 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 */
|
||||
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;
|
||||
|
||||
/* 4. set secondary policy data */
|
||||
/* 5. 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)))
|
||||
@@ -130,9 +136,18 @@ acm_get_policy(void *buf, u32 buf_size)
|
||||
bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
|
||||
|
||||
bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
|
||||
bin_pol->policy_reference_offset = htonl(ntohl(bin_pol->len));
|
||||
bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
|
||||
bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
|
||||
|
||||
ret = acm_dump_policy_reference(policy_buffer + ntohl(bin_pol->policy_reference_offset),
|
||||
buf_size - ntohl(bin_pol->policy_reference_offset));
|
||||
if (ret < 0)
|
||||
goto error_free_unlock;
|
||||
|
||||
bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
|
||||
bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
|
||||
|
||||
ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset),
|
||||
buf_size - ntohl(bin_pol->primary_buffer_offset));
|
||||
if (ret < 0)
|
||||
@@ -227,6 +242,14 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
|
||||
acm_ssid->ssidref = ssidref;
|
||||
acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
|
||||
acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
|
||||
|
||||
acm_ssid->policy_reference_offset = acm_ssid->len;
|
||||
ret = acm_dump_policy_reference(ssid_buffer + acm_ssid->policy_reference_offset,
|
||||
buf_size - acm_ssid->policy_reference_offset);
|
||||
if (ret < 0)
|
||||
goto error_free_unlock;
|
||||
|
||||
acm_ssid->len += ret;
|
||||
acm_ssid->primary_types_offset = acm_ssid->len;
|
||||
|
||||
/* ret >= 0 --> ret == max_types */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
/* Xen-internal representation of the binary policy */
|
||||
struct acm_binary_policy {
|
||||
char *policy_reference_name;
|
||||
u16 primary_policy_code;
|
||||
u16 secondary_policy_code;
|
||||
};
|
||||
@@ -124,7 +125,8 @@ 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_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, enum acm_hook_type hook);
|
||||
|
||||
int acm_set_policy_reference(u8 * buf, u32 buf_size);
|
||||
int acm_dump_policy_reference(u8 *buf, u32 buf_size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -51,17 +51,17 @@
|
||||
|
||||
/* policy: */
|
||||
#define ACM_POLICY_NAME(X) \
|
||||
((X) == (ACM_NULL_POLICY)) ? "NULL policy" : \
|
||||
((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL policy" : \
|
||||
((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT policy" : \
|
||||
((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
|
||||
"UNDEFINED policy"
|
||||
((X) == (ACM_NULL_POLICY)) ? "NULL" : \
|
||||
((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL" : \
|
||||
((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT" : \
|
||||
((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT" : \
|
||||
"UNDEFINED"
|
||||
|
||||
/* the following policy versions must be increased
|
||||
* whenever the interpretation of the related
|
||||
* policy's data structure changes
|
||||
*/
|
||||
#define ACM_POLICY_VERSION 1
|
||||
#define ACM_POLICY_VERSION 2
|
||||
#define ACM_CHWALL_VERSION 1
|
||||
#define ACM_STE_VERSION 1
|
||||
|
||||
@@ -113,12 +113,17 @@ struct acm_policy_buffer {
|
||||
uint32_t policy_version; /* ACM_POLICY_VERSION */
|
||||
uint32_t magic;
|
||||
uint32_t len;
|
||||
uint32_t policy_reference_offset;
|
||||
uint32_t primary_policy_code;
|
||||
uint32_t primary_buffer_offset;
|
||||
uint32_t secondary_policy_code;
|
||||
uint32_t secondary_buffer_offset;
|
||||
};
|
||||
|
||||
struct acm_policy_reference_buffer {
|
||||
uint32_t len;
|
||||
};
|
||||
|
||||
struct acm_chwall_policy_buffer {
|
||||
uint32_t policy_version; /* ACM_CHWALL_VERSION */
|
||||
uint32_t policy_code;
|
||||
@@ -160,6 +165,7 @@ struct acm_ste_stats_buffer {
|
||||
struct acm_ssid_buffer {
|
||||
uint32_t len;
|
||||
ssidref_t ssidref;
|
||||
uint32_t policy_reference_offset;
|
||||
uint32_t primary_policy_code;
|
||||
uint32_t primary_max_types;
|
||||
uint32_t primary_types_offset;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* This makes sure that old versions of acm tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*/
|
||||
#define ACM_INTERFACE_VERSION 0xAAAA0005
|
||||
#define ACM_INTERFACE_VERSION 0xAAAA0006
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
||||