--- xen-unstable.hg/tools/python/xen/util/acmpolicy.py | 31 ++- xen-unstable.hg/tools/python/xen/util/security.py | 8 xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py | 2 xen-unstable.hg/tools/python/xen/xend/server/blkif.py | 27 +-- xen-unstable.hg/tools/python/xen/xm/main.py | 3 xen-unstable.hg/tools/security/xensec_ezpolicy | 7 xen-unstable.hg/xen/acm/acm_chinesewall_hooks.c | 103 +++++++----- xen-unstable.hg/xen/acm/acm_simple_type_enforcement_hooks.c | 2 8 files changed, 116 insertions(+), 67 deletions(-) Index: root/xen-unstable.hg/tools/python/xen/xm/main.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/xm/main.py +++ root/xen-unstable.hg/tools/python/xen/xm/main.py @@ -50,6 +50,7 @@ from xen.xm.opts import OptionError, Opt from xen.xm import console from xen.util.xmlrpcclient import ServerProxy from xen.util.security import ACMError +from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY import XenAPI @@ -947,7 +948,7 @@ def xm_label_list(doms): d = parse_doms_info(dom) if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']: if not d['seclabel']: - d['seclabel'] = 'ERROR' + d['seclabel'] = ACM_LABEL_UNLABELED_DISPLAY elif security.active_policy in ['DEFAULT']: d['seclabel'] = 'DEFAULT' else: Index: root/xen-unstable.hg/xen/acm/acm_chinesewall_hooks.c =================================================================== --- root.orig/xen-unstable.hg/xen/acm/acm_chinesewall_hooks.c +++ root/xen-unstable.hg/xen/acm/acm_chinesewall_hooks.c @@ -93,6 +93,7 @@ int acm_init_chwall_policy(void) return ACM_OK; } + static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) { struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); @@ -104,10 +105,10 @@ static int chwall_init_domain_ssid(void chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if ( (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) - || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) ) + if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs ) { - printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n", + printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset " + "(0).\n", __func__, chwall_ssidp->chwall_ssidref); xfree(chwall_ssidp); return ACM_INIT_SSID_ERROR; @@ -118,6 +119,7 @@ static int chwall_init_domain_ssid(void return ACM_OK; } + static void chwall_free_domain_ssid(void *chwall_ssid) { xfree(chwall_ssid); @@ -205,7 +207,9 @@ chwall_init_state(struct acm_chwall_poli read_lock(&ssid_list_rwlock); - /* go through all domains and adjust policy as if this domain was started now */ + /* go through all domains and adjust policy as if this domain was + * started now + */ for_each_acmssid( rawssid ) { chwall_ssid = @@ -220,8 +224,8 @@ chwall_init_state(struct acm_chwall_poli /* b) check for conflict */ for ( i = 0; i < chwall_buf->chwall_max_types; i++ ) - if (conflict_aggregate_set[i] && - ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]) + if ( conflict_aggregate_set[i] && + ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i] ) { printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); @@ -231,37 +235,46 @@ chwall_init_state(struct acm_chwall_poli goto out; } + /* set violation and break out of the loop */ - /* c) adapt conflict aggregate set for this domain (notice conflicts) */ + /* c) adapt conflict aggregate set for this domain + * (notice conflicts) + */ for ( i = 0; i < chwall_buf->chwall_max_conflictsets; i++ ) { int common = 0; /* check if conflict_set_i and ssidref have common types */ for ( j = 0; j < chwall_buf->chwall_max_types; j++ ) - if (conflict_sets[i * chwall_buf->chwall_max_types + j] && - ssidrefs[chwall_ssidref * - chwall_buf->chwall_max_types + j]) + if ( conflict_sets[i * chwall_buf->chwall_max_types + j] && + ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j] ) { common = 1; break; } - if (common == 0) + + if ( common == 0 ) continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + + /* now add types of the conflict set to conflict_aggregate_set + * (except types in chwall_ssidref) + */ for ( j = 0; j < chwall_buf->chwall_max_types; j++ ) - if (conflict_sets[i * chwall_buf->chwall_max_types + j] && - !ssidrefs[chwall_ssidref * - chwall_buf->chwall_max_types + j]) + if ( conflict_sets[i * chwall_buf->chwall_max_types + j] && + !ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j] ) conflict_aggregate_set[j]++; } } out: read_unlock(&ssid_list_rwlock); return violation; - /* returning "violation != 0" means that the currently running set of domains would - * not be possible if the new policy had been enforced before starting them; for chinese - * wall, this means that the new policy includes at least one conflict set of which - * more than one type is currently running */ + /* returning "violation != 0" means that the currently running set of + * domains would not be possible if the new policy had been enforced + * before starting them; for chinese wall, this means that the new + * policy includes at least one conflict set of which more than one + * type is currently running + */ } @@ -348,8 +361,10 @@ static int _chwall_update_policy(u8 *buf memset(conflict_aggregate_set, 0, sizeof(domaintype_t) * chwall_buf->chwall_max_types); - /* 3. now re-calculate the state for the new policy based on running domains; - * this can fail if new policy is conflicting with running domains */ + /* 3. now re-calculate the state for the new policy based on + * running domains; this can fail if new policy is conflicting + * with running domains + */ if ( chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set, @@ -483,31 +498,27 @@ static int _chwall_pre_domain_create(voi chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) - { - printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", - __func__); - return ACM_ACCESS_DENIED; /* catching and indicating config error */ - } - - if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) + if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs ) { printk("%s: ERROR chwall_ssidref > max(%x).\n", __func__, chwall_bin_pol.max_ssidrefs - 1); return ACM_ACCESS_DENIED; } + /* A: chinese wall check for conflicts */ - for (i = 0; i < chwall_bin_pol.max_types; i++) - if (chwall_bin_pol.conflict_aggregate_set[i] && - chwall_bin_pol.ssidrefs[chwall_ssidref * - chwall_bin_pol.max_types + i]) + for ( i = 0; i < chwall_bin_pol.max_types; i++ ) + if ( chwall_bin_pol.conflict_aggregate_set[i] && + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i] ) { printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); return ACM_ACCESS_DENIED; } /* B: chinese wall conflict set adjustment (so that other - * other domains simultaneously created are evaluated against this new set)*/ + * other domains simultaneously created are evaluated against + * this new set) + */ for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ ) { int common = 0; @@ -521,7 +532,7 @@ static int _chwall_pre_domain_create(voi common = 1; break; } - if (common == 0) + if ( common == 0 ) continue; /* try next conflict set */ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ for ( j = 0; j < chwall_bin_pol.max_types; j++ ) @@ -571,9 +582,15 @@ static void _chwall_post_domain_create(d common = 1; break; } + if ( common == 0 ) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + { + /* try next conflict set */ + continue; + } + + /* now add types of the conflict set to conflict_aggregate_set + (except types in chwall_ssidref) */ for ( j = 0; j < chwall_bin_pol.max_types; j++ ) if ( chwall_bin_pol. conflict_sets[i * chwall_bin_pol.max_types + j] @@ -638,9 +655,15 @@ static void chwall_domain_destroy(void * common = 1; break; } - if (common == 0) - continue; /* try next conflict set, this one does not include any type of chwall_ssidref */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + if ( common == 0 ) + { + /* try next conflict set, this one does not include + any type of chwall_ssidref */ + continue; + } + + /* now add types of the conflict set to conflict_aggregate_set + (except types in chwall_ssidref) */ for ( j = 0; j < chwall_bin_pol.max_types; j++ ) if ( chwall_bin_pol. conflict_sets[i * chwall_bin_pol.max_types + j] Index: root/xen-unstable.hg/tools/python/xen/util/security.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/util/security.py +++ root/xen-unstable.hg/tools/python/xen/util/security.py @@ -155,7 +155,7 @@ def calc_dom_ssidref_from_info(info): ssidref = label2ssidref(vmlabel, policyname, "dom") return ssidref else: - return 0 + return 0x0 raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'" "not supported." % type(info)) @@ -232,6 +232,10 @@ def ssidref2label(ssidref_var): else: err("Instance type of ssidref not supported (must be of type 'str' or 'int')") + if ssidref == 0: + from xen.util.acmpolicy import ACM_LABEL_UNLABELED + return ACM_LABEL_UNLABELED + try: mapfile_lock() @@ -867,7 +871,7 @@ def get_domain_resources(dominfo): resources[typ].append("%s:%s:%s" % (xsconstants.ACM_POLICY_ID, active_policy, - "unlabeled")) + ACM_LABEL_UNLABELED)) return resources Index: root/xen-unstable.hg/tools/python/xen/xend/server/blkif.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/xend/server/blkif.py +++ root/xen-unstable.hg/tools/python/xen/xend/server/blkif.py @@ -73,17 +73,7 @@ class BlkifController(DevController): back['uuid'] = uuid if security.on(): - (label, ssidref, policy) = \ - security.get_res_security_details(uname) - domain_label = self.vm.get_security_label() - if domain_label: - rc = security.res_security_check_xapi(label, ssidref, policy, - domain_label) - if rc == 0: - raise VmError("VM's access to block device '%s' denied." % - uname) - else: - raise VmError("VM must have a security label.") + self.do_access_control(config, uname) devid = blkif.blkdev_name_to_number(dev) if devid is None: @@ -95,6 +85,21 @@ class BlkifController(DevController): return (devid, back, front) + def do_access_control(self, config, uname): + (label, ssidref, policy) = \ + security.get_res_security_details(uname) + domain_label = self.vm.get_security_label() + if domain_label: + rc = security.res_security_check_xapi(label, ssidref, policy, + domain_label) + if rc == 0: + raise VmError("VM's access to block device '%s' denied" % + uname) + else: + from xen.util.acmpolicy import ACM_LABEL_UNLABELED + if label != ACM_LABEL_UNLABELED: + raise VmError("VM must have a security label to access " + "block device '%s'" % uname) def reconfigureDevice(self, _, config): """@see DevController.reconfigureDevice""" 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 @@ -47,6 +47,9 @@ ACM_POLICY_UNDEFINED = 15 ACM_SCHEMA_FILE = "/etc/xen/acm-security/policies/security_policy.xsd" +ACM_LABEL_UNLABELED = "__UNLABELED__" +ACM_LABEL_UNLABELED_DISPLAY = "unlabeled" + class ACMPolicy(XSPolicy): """ ACMPolicy class. Implements methods for getting information from @@ -925,11 +928,13 @@ class ACMPolicy(XSPolicy): return -xsconstants.XSERR_POLICY_INCONSISTENT, "", "" vms_with_chws = [] - chws_by_vm = {} + chws_by_vm = { ACM_LABEL_UNLABELED : [] } for v in vms: if v.has_key("chws"): vms_with_chws.append(v["name"]) chws_by_vm[v["name"]] = v["chws"] + + if bootstrap in vms_with_chws: vms_with_chws.remove(bootstrap) vms_with_chws.sort() @@ -937,12 +942,16 @@ class ACMPolicy(XSPolicy): else: vms_with_chws.sort() + if ACM_LABEL_UNLABELED in vms_with_chws: + vms_with_chws.remove(ACM_LABEL_UNLABELED) ; # @1 + vms_with_stes = [] - stes_by_vm = {} + stes_by_vm = { ACM_LABEL_UNLABELED : [] } for v in vms: if v.has_key("stes"): vms_with_stes.append(v["name"]) stes_by_vm[v["name"]] = v["stes"] + if bootstrap in vms_with_stes: vms_with_stes.remove(bootstrap) vms_with_stes.sort() @@ -950,6 +959,9 @@ class ACMPolicy(XSPolicy): else: vms_with_stes.sort() + if ACM_LABEL_UNLABELED in vms_with_stes: + vms_with_stes.remove(ACM_LABEL_UNLABELED) ; # @2 + resnames = self.policy_get_resourcelabel_names() resnames.sort() stes_by_res = {} @@ -958,6 +970,9 @@ class ACMPolicy(XSPolicy): if r.has_key("stes"): stes_by_res[r["name"]] = r["stes"] + if ACM_LABEL_UNLABELED in resnames: + resnames.remove(ACM_LABEL_UNLABELED) + max_chw_ssids = 1 + len(vms_with_chws) max_chw_types = 1 + len(vms_with_chws) max_ste_ssids = 1 + len(vms_with_stes) + len(resnames) @@ -1083,6 +1098,8 @@ class ACMPolicy(XSPolicy): pr_bin += "\x00" # Build chinese wall part + vms_with_chws.insert(0, ACM_LABEL_UNLABELED) + cfses_names = self.policy_get_chwall_cfses_names_sorted() cfses = self.policy_get_chwall_cfses() @@ -1105,9 +1122,7 @@ class ACMPolicy(XSPolicy): chw_running_types_offset, chw_conf_agg_offset) chw_bin_body = "" - # simulate __NULL_LABEL__ - for c in chws: - chw_bin_body += struct.pack("!h",0) + # VMs that are listed and their chinese walls for v in vms_with_chws: for c in chws: @@ -1143,6 +1158,8 @@ class ACMPolicy(XSPolicy): chw_bin += "\x00" # Build STE part + vms_with_stes.insert(0, ACM_LABEL_UNLABELED) # Took out in @2 + steformat="!iiiii" ste_bin = struct.pack(steformat, ACM_STE_VERSION, @@ -1152,10 +1169,7 @@ class ACMPolicy(XSPolicy): struct.calcsize(steformat)) ste_bin_body = "" if stes: - # Simulate __NULL_LABEL__ - for s in stes: - ste_bin_body += struct.pack("!h",0) - # VMs that are listed and their chinese walls + # VMs that are listed and their STE types for v in vms_with_stes: unknown_ste |= (set(stes_by_vm[v]) - set(stes)) for s in stes: Index: root/xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- root.orig/xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py +++ root/xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py @@ -1463,8 +1463,6 @@ class XendDomainInfo: ssidref = 0 if security.on(): ssidref = security.calc_dom_ssidref_from_info(self.info) - if ssidref == 0: - raise VmError('VM is not properly labeled.') if security.has_authorization(ssidref) == False: raise VmError("VM is not authorized to run.") Index: root/xen-unstable.hg/tools/security/xensec_ezpolicy =================================================================== --- root.orig/xen-unstable.hg/tools/security/xensec_ezpolicy +++ root/xen-unstable.hg/tools/security/xensec_ezpolicy @@ -36,6 +36,8 @@ conflict_bmp = None realm_icon = None workload_icon = None +ACM_LABEL_UNLABELED = '__UNLABELED__' + class orgTreeCtrl(wx.TreeCtrl): event = None @@ -870,7 +872,8 @@ class ezFrame(wx.Frame): self.realm_menu.Enable(self.ID_ORGDEL, True) self.realm_menu.Enable(self.ID_ORGEDT, True) self.realm_menu.Enable(self.ID_ORGADD, True) - if len(self.orgs.GetSelections()) > 1: + if len(self.orgs.GetSelections()) > 1 or \ + ACM_LABEL_UNLABELED == self.orgs.GetItemText(item): self.realm_menu.Enable(self.ID_ORGEDT, False) self.realm_menu.Enable(self.ID_ORGADD, False) self.PopupMenu(self.realm_menu) @@ -1622,6 +1625,8 @@ def main(): app = ezApp(0) if len(sys.argv) in [2]: app.Load(sys.argv[1]) + else: + dict2org({'orgs' : [[ACM_LABEL_UNLABELED,[]]], 'cons': []}) app.MainLoop() print "Goodbye" Index: root/xen-unstable.hg/xen/acm/acm_simple_type_enforcement_hooks.c =================================================================== --- root.orig/xen-unstable.hg/xen/acm/acm_simple_type_enforcement_hooks.c +++ root/xen-unstable.hg/xen/acm/acm_simple_type_enforcement_hooks.c @@ -408,7 +408,7 @@ _ste_update_policy(u8 *buf, u32 buf_size ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; - if ( ste_init_state(NULL) ) + if ( ste_init_state(errors) ) { /* new policy conflicts with sharing of running domains */ printk("%s: New policy conflicts with running domains. "