Index: root/xen-unstable.hg/tools/python/xen/util/acmpolicy.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/util/acmpolicy.py +++ root/xen-unstable.hg/tools/python/xen/util/acmpolicy.py @@ -17,6 +17,7 @@ #============================================================================ import os +import sha import stat import array import struct @@ -35,7 +36,7 @@ ACM_POLICIES_DIR = security.policy_dir_p # Constants needed for generating a binary policy from its XML # representation -ACM_POLICY_VERSION = 3 # Latest one +ACM_POLICY_VERSION = 4 # Latest one ACM_CHWALL_VERSION = 1 ACM_STE_VERSION = 1 @@ -965,6 +966,10 @@ class ACMPolicy(XSPolicy): return dom.toxml() return None + def hash(self): + """ Calculate a SAH1 hash of the XML policy """ + return sha.sha(self.toxml()) + def save(self): ### Save the XML policy into a file ### rc = -xsconstants.XSERR_FILE_ERROR @@ -1403,7 +1408,7 @@ class ACMPolicy(XSPolicy): ste_bin += "\x00" #Write binary header: - headerformat="!iiiiiiiiii" + headerformat="!iiiiiiiiii20s" totallen_bin = struct.calcsize(headerformat) + \ len(pr_bin) + len(chw_bin) + len(ste_bin) polref_offset = struct.calcsize(headerformat) @@ -1425,7 +1430,8 @@ class ACMPolicy(XSPolicy): primpoloffset, secpolcode, secpoloffset, - major, minor) + major, minor, + self.hash().digest()) all_bin = array.array('B') for s in [ hdr_bin, pr_bin, chw_bin, ste_bin ]: @@ -1443,6 +1449,21 @@ class ACMPolicy(XSPolicy): rc = -xsconstants.XSERR_BAD_LABEL return rc, mapfile, all_bin.tostring() + def validate_enforced_policy_hash(self): + """ verify that the policy hash embedded in the binary policy + that is currently enforce matches the one of the XML policy. + """ + if self.hash().digest() != self.get_enforced_policy_hash(): + raise Exception('Policy hashes do not match') + + def get_enforced_policy_hash(self): + binpol = self.get_enforced_binary() + headerformat="!iiiiiiiiii20s" + res = struct.unpack(headerformat, binpol[:60]) + if len(res) >= 11: + return res[10] + return None + def get_enforced_binary(self): rc, binpol = security.hv_get_policy() if rc != 0: Index: root/xen-unstable.hg/tools/python/xen/xend/XendXSPolicyAdmin.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/xend/XendXSPolicyAdmin.py +++ root/xen-unstable.hg/tools/python/xen/xend/XendXSPolicyAdmin.py @@ -54,6 +54,7 @@ class XSPolicyAdmin: try: self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref) self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID) + self.xsobjs[ref].validate_enforced_policy_hash() except Exception, e: log.error("Could not find XML representation of policy '%s': " "%s" % (act_pol_name,e)) Index: root/xen-unstable.hg/xen/include/public/xsm/acm.h =================================================================== --- root.orig/xen-unstable.hg/xen/include/public/xsm/acm.h +++ root/xen-unstable.hg/xen/include/public/xsm/acm.h @@ -91,7 +91,7 @@ * whenever the interpretation of the related * policy's data structure changes */ -#define ACM_POLICY_VERSION 3 +#define ACM_POLICY_VERSION 4 #define ACM_CHWALL_VERSION 1 #define ACM_STE_VERSION 1 @@ -131,6 +131,10 @@ typedef uint16_t domaintype_t; /* high-16 = version, low-16 = check magic */ #define ACM_MAGIC 0x0001debc +/* size of the SHA1 hash identifying the XML policy from which the + binary policy was created */ +#define ACM_SHA1_HASH_SIZE 20 + /* each offset in bytes from start of the struct they * are part of */ @@ -160,6 +164,7 @@ struct acm_policy_buffer { uint32_t secondary_policy_code; uint32_t secondary_buffer_offset; struct acm_policy_version xml_pol_version; /* add in V3 */ + uint8_t xml_policy_hash[ACM_SHA1_HASH_SIZE]; /* added in V4 */ }; Index: root/xen-unstable.hg/xen/xsm/acm/acm_policy.c =================================================================== --- root.orig/xen-unstable.hg/xen/xsm/acm/acm_policy.c +++ root/xen-unstable.hg/xen/xsm/acm/acm_policy.c @@ -156,6 +156,10 @@ _acm_update_policy(void *buf, u32 buf_si &pol->xml_pol_version, sizeof(acm_bin_pol.xml_pol_version)); + memcpy(&acm_bin_pol.xml_policy_hash, + pol->xml_policy_hash, + sizeof(acm_bin_pol.xml_policy_hash)); + if ( acm_primary_ops->is_default_policy() && acm_secondary_ops->is_default_policy() ) require_update = 0; @@ -258,6 +262,10 @@ acm_get_policy(XEN_GUEST_HANDLE_64(void) &acm_bin_pol.xml_pol_version, sizeof(struct acm_policy_version)); + memcpy(&bin_pol->xml_policy_hash, + &acm_bin_pol.xml_policy_hash, + sizeof(acm_bin_pol.xml_policy_hash)); + ret = acm_dump_policy_reference( policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset), buf_size - be32_to_cpu(bin_pol->policy_reference_offset)); Index: root/xen-unstable.hg/xen/include/xsm/acm/acm_core.h =================================================================== --- root.orig/xen-unstable.hg/xen/include/xsm/acm/acm_core.h +++ root/xen-unstable.hg/xen/include/xsm/acm/acm_core.h @@ -34,6 +34,7 @@ struct acm_binary_policy { u16 primary_policy_code; u16 secondary_policy_code; struct acm_policy_version xml_pol_version; + u8 xml_policy_hash[ACM_SHA1_HASH_SIZE]; }; struct chwall_binary_policy {