mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[ACM] Support for running unlabeled domains alongside labeled ones
Add support for running unlabeled domains alongside labeled ones, if the policy contains a VM label with name '__UNLABELED__' and an STE type with the same name. The ezpolicy tool has been modified to automatically suggest a policy under which unlabeled domains can run. The user may delete this, if this is not desired. Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
1 parent
5a9b83aea8
commit
b163ba1607
8 files changed
+117
-67
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.")
|
||||
|
||||
|
||||
@@ -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"""
|
||||
|
||||
@@ -51,6 +51,7 @@ from xen.xm.opts import OptionError, Opts, wrap, set_true
|
||||
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:
|
||||
|
||||