]> xenbits.xensource.com Git - xen.git/commitdiff
ACM: Put hash of XML policy into binary policy to tie them together
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 23 Apr 2008 12:29:09 +0000 (13:29 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 23 Apr 2008 12:29:09 +0000 (13:29 +0100)
This patch extends the ACM binary policy format with an embedded hash
of the corresponding XML policy in order to tie them together. This
allows xend to determine whether it has the correct XML policy in its
repository and react appropriately if it does not have it.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
tools/python/xen/util/acmpolicy.py
tools/python/xen/xend/XendXSPolicyAdmin.py
xen/include/public/xsm/acm.h
xen/include/xsm/acm/acm_core.h
xen/xsm/acm/acm_policy.c

index 89ee983600c403a0775b8bde007a3133cbdf8441..f0f5601a8cf93451e9744578ae5b533c634737bc 100644 (file)
@@ -17,6 +17,7 @@
 #============================================================================
 
 import os
+import sha
 import stat
 import array
 import struct
@@ -35,7 +36,7 @@ ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
 
 # 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 cf10ef2df4ed1879fb270685c785fd4f081db355..633c62b228eed826b7edcd5a1512513be5126d6a 100644 (file)
@@ -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 a66d399c6cd7d474893851ea7b8cf0df250d6768..4417c30f0ebc6470f83f833210f410d4544c71b6 100644 (file)
@@ -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 df6ea6385198e87b66707636457fbf959bd9b18f..718f9b7f89f7926d70f1aea17aec0fb6c9abcd6e 100644 (file)
@@ -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 {
index 3f66e8ae73e089bfdb2df914052dd6a32dfd1edd..31219d9aae3aa56b8299a7c7aa9632f7454a4d7c 100644 (file)
@@ -156,6 +156,10 @@ _acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy,
            &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) buf, u32 buf_size)
            &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));