direct-io.hg

changeset 10341:0de8a4a023d0

[ACM] Provide the framework needed for resource labeling.

Subsequent patches will follow in the coming weeks that will enable
Xen ACM to control assignment of resources (e.g., block devices and
networking) to virtual machines based on resource labels and the
active security policy.

Signed-off-by: Bryan D. Payne <bdpayne@us.ibm.com>
Signed-off-by: Reiner Sailer <sailer@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Jun 13 15:38:58 2006 +0100 (2006-06-13)
parents 88d867661599
children 5d4b9dc88218
files tools/python/xen/util/security.py tools/python/xen/xm/addlabel.py tools/python/xen/xm/create.py tools/security/Makefile tools/security/python/xensec_gen/cgi-bin/policy.cgi tools/security/secpol_xml2bin.c
line diff
     1.1 --- a/tools/python/xen/util/security.py	Tue Jun 13 15:33:10 2006 +0100
     1.2 +++ b/tools/python/xen/util/security.py	Tue Jun 13 15:38:58 2006 +0100
     1.3 @@ -52,7 +52,8 @@ empty_line_re = re.compile("^\s*$")
     1.4  binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
     1.5  policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
     1.6  
     1.7 -
     1.8 +#other global variables
     1.9 +NULL_SSIDREF = 0
    1.10  
    1.11  log = logging.getLogger("xend.util.security")
    1.12  
    1.13 @@ -255,6 +256,8 @@ def ssidref2label(ssidref_var):
    1.14      #2. get labelnames for both ssidref parts
    1.15      pri_ssid = ssidref & 0xffff
    1.16      sec_ssid = ssidref >> 16
    1.17 +    pri_null_ssid = NULL_SSIDREF & 0xffff
    1.18 +    sec_null_ssid = NULL_SSIDREF >> 16
    1.19      pri_labels = []
    1.20      sec_labels = []
    1.21      labels = []
    1.22 @@ -270,7 +273,11 @@ def ssidref2label(ssidref_var):
    1.23      f.close()
    1.24  
    1.25      #3. get the label that is in both lists (combination must be a single label)
    1.26 -    if secondary == "NULL":
    1.27 +    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid):
    1.28 +        labels = sec_labels
    1.29 +    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid):
    1.30 +        labels = pri_labels
    1.31 +    elif secondary == "NULL":
    1.32          labels = pri_labels
    1.33      else:
    1.34          for i in pri_labels:
    1.35 @@ -285,7 +292,7 @@ def ssidref2label(ssidref_var):
    1.36  
    1.37  
    1.38  
    1.39 -def label2ssidref(labelname, policyname):
    1.40 +def label2ssidref(labelname, policyname, type):
    1.41      """
    1.42      returns ssidref corresponding to labelname;
    1.43      maps current policy to default directory
    1.44 @@ -294,6 +301,14 @@ def label2ssidref(labelname, policyname)
    1.45      if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
    1.46          err("Cannot translate labels for \'" + policyname + "\' policy.")
    1.47  
    1.48 +    allowed_types = ['ANY']
    1.49 +    if type == 'dom':
    1.50 +        allowed_types.append('VM')
    1.51 +    elif type == 'res':
    1.52 +        allowed_types.append('RES')
    1.53 +    else:
    1.54 +        err("Invalid type.  Must specify 'dom' or 'res'.")
    1.55 +
    1.56      (primary, secondary, f, pol_exists) = getmapfile(policyname)
    1.57  
    1.58      #2. get labelnames for ssidref parts and find a common label
    1.59 @@ -303,11 +318,15 @@ def label2ssidref(labelname, policyname)
    1.60          l = line.split()
    1.61          if (len(l) < 5) or (l[0] != "LABEL->SSID"):
    1.62              continue
    1.63 -        if primary and (l[2] == primary) and (l[3] == labelname):
    1.64 +        if primary and (l[1] in allowed_types) and (l[2] == primary) and (l[3] == labelname):
    1.65              pri_ssid.append(int(l[4], 16))
    1.66 -        if secondary and (l[2] == secondary) and (l[3] == labelname):
    1.67 +        if secondary and (l[1] in allowed_types) and (l[2] == secondary) and (l[3] == labelname):
    1.68              sec_ssid.append(int(l[4], 16))
    1.69      f.close()
    1.70 +    if (type == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
    1.71 +        pri_ssid.append(NULL_SSIDREF)
    1.72 +    elif (type == 'res') and (secondary == "CHWALL") and (len(sec_ssid) == 0):
    1.73 +        sec_ssid.append(NULL_SSIDREF)
    1.74  
    1.75      #3. sanity check and composition of ssidref
    1.76      if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and (secondary != "NULL")):
    1.77 @@ -360,7 +379,7 @@ def refresh_ssidref(config):
    1.78          err("Policy \'" + policyname + "\' in label does not match active policy \'"
    1.79              + active_policy +"\'!")
    1.80  
    1.81 -    new_ssidref = label2ssidref(labelname, policyname)
    1.82 +    new_ssidref = label2ssidref(labelname, policyname, 'dom')
    1.83      if not new_ssidref:
    1.84          err("SSIDREF refresh failed!")
    1.85  
    1.86 @@ -409,7 +428,7 @@ def get_decision(arg1, arg2):
    1.87      enables domains to retrieve access control decisions from
    1.88      the hypervisor Access Control Module.
    1.89      IN: args format = ['domid', id] or ['ssidref', ssidref]
    1.90 -    or ['access_control', ['policy', policy], ['label', label]]
    1.91 +    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
    1.92      """
    1.93  
    1.94      if not on():
    1.95 @@ -417,14 +436,14 @@ def get_decision(arg1, arg2):
    1.96  
    1.97      #translate labels before calling low-level function
    1.98      if arg1[0] == 'access_control':
    1.99 -        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') :
   1.100 +        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'):
   1.101              err("Argument type not supported.")
   1.102 -        ssidref = label2ssidref(arg1[2][1], arg1[1][1])
   1.103 +        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
   1.104          arg1 = ['ssidref', str(ssidref)]
   1.105      if arg2[0] == 'access_control':
   1.106 -        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') :
   1.107 +        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'):
   1.108              err("Argument type not supported.")
   1.109 -        ssidref = label2ssidref(arg2[2][1], arg2[1][1])
   1.110 +        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
   1.111          arg2 = ['ssidref', str(ssidref)]
   1.112  
   1.113      # accept only int or string types for domid and ssidref
     2.1 --- a/tools/python/xen/xm/addlabel.py	Tue Jun 13 15:33:10 2006 +0100
     2.2 +++ b/tools/python/xen/xm/addlabel.py	Tue Jun 13 15:38:58 2006 +0100
     2.3 @@ -50,7 +50,7 @@ def main(argv):
     2.4              err("No active policy. Policy must be specified in command line.")
     2.5  
     2.6          #sanity checks: make sure this label can be instantiated later on
     2.7 -        ssidref = label2ssidref(label, policyref)
     2.8 +        ssidref = label2ssidref(label, policyref, 'dom')
     2.9  
    2.10          new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label)
    2.11          if not os.path.isfile(configfile):
     3.1 --- a/tools/python/xen/xm/create.py	Tue Jun 13 15:33:10 2006 +0100
     3.2 +++ b/tools/python/xen/xm/create.py	Tue Jun 13 15:38:58 2006 +0100
     3.3 @@ -541,7 +541,7 @@ def configure_security(config, vals):
     3.4          if sxp.child_value(config, 'ssidref'):
     3.5              err("ERROR: SSIDREF and access_control are mutually exclusive but both specified!")
     3.6          #else calculate ssidre from label
     3.7 -        ssidref = security.label2ssidref(label, policy)
     3.8 +        ssidref = security.label2ssidref(label, policy, 'dom')
     3.9          if not ssidref :
    3.10              err("ERROR calculating ssidref from access_control.")
    3.11          security_label = ['security', [ config_access_control, ['ssidref' , ssidref ] ] ]
     4.1 --- a/tools/security/Makefile	Tue Jun 13 15:33:10 2006 +0100
     4.2 +++ b/tools/security/Makefile	Tue Jun 13 15:38:58 2006 +0100
     4.3 @@ -33,7 +33,7 @@ OBJS_XML2BIN := $(patsubst %.c,%.o,$(fil
     4.4  
     4.5  ACM_INST_TOOLS    = xensec_tool xensec_xml2bin xensec_gen
     4.6  ACM_OBJS          = $(OBJS_TOOL) $(OBJS_XML2BIN) $(OBJS_GETD)
     4.7 -ACM_SCRIPTS       = python/xensec_tools/acm_getlabel python/xensec_tools/acm_getdecision
     4.8 +ACM_SCRIPTS       = python/xensec_tools/acm_getlabel
     4.9  
    4.10  ACM_CONFIG_DIR    = /etc/xen/acm-security
    4.11  ACM_POLICY_DIR    = $(ACM_CONFIG_DIR)/policies
     5.1 --- a/tools/security/python/xensec_gen/cgi-bin/policy.cgi	Tue Jun 13 15:33:10 2006 +0100
     5.2 +++ b/tools/security/python/xensec_gen/cgi-bin/policy.cgi	Tue Jun 13 15:38:58 2006 +0100
     5.3 @@ -406,7 +406,7 @@ def parsePolicyXml( ):
     5.4  					msg = msg + 'Please validate the Policy file used.'
     5.5  					formatXmlError( msg )
     5.6  
     5.7 -					allCSMTypes[csName][1] = csMemberList
     5.8 +				allCSMTypes[csName][1] = csMemberList
     5.9  
    5.10  	if pOrder != '':
    5.11  		formPolicyOrder[1] = pOrder
     6.1 --- a/tools/security/python/xensec_tools/acm_getdecision	Tue Jun 13 15:33:10 2006 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,55 +0,0 @@
     6.4 -#!/usr/bin/env python
     6.5 -#  -*- mode: python; -*-
     6.6 -import sys
     6.7 -import traceback
     6.8 -import getopt
     6.9 -
    6.10 -# add fallback path for non-native python path installs if needed
    6.11 -sys.path.insert(-1, '/usr/lib/python')
    6.12 -sys.path.insert(-1, '/usr/lib64/python')
    6.13 -
    6.14 -from xen.util.security import ACMError, err, get_decision, active_policy
    6.15 -
    6.16 -def usage():
    6.17 -    print "Usage: acm_getdecision -i domainid --label labelname"
    6.18 -    print "  Test program illustrating the retrieval of"
    6.19 -    print "  access control decisions from Xen. At this time,"
    6.20 -    print "  only sharing (STE) policy decisions are supported."
    6.21 -    print "  Arguments are two paramters in any combination:"
    6.22 -    print "\t -i domain_id or --domid domain_id"
    6.23 -    print "\t -l labelname or --label labelname"
    6.24 -    print "  Return value:"
    6.25 -    print "\t PERMITTED if access is permitted"
    6.26 -    print "\t DENIED if access is denied"
    6.27 -    print "\t ACMError -- e.g., unknown label or domain id"
    6.28 -    err("Usage")
    6.29 -
    6.30 -try:
    6.31 -
    6.32 -    if len(sys.argv) != 5:
    6.33 -        usage()
    6.34 -
    6.35 -    decision_args = []
    6.36 -
    6.37 -    for idx in range(1, len(sys.argv), 2):
    6.38 -        if sys.argv[idx] in ['-i', '--domid']:
    6.39 -            decision_args.append(['domid', sys.argv[idx+1]])
    6.40 -        elif sys.argv[idx] in ['-l', '--label']:
    6.41 -            decision_args.append(['access_control',
    6.42 -                                  ['policy', active_policy],
    6.43 -                                  ['label', sys.argv[idx+1]]
    6.44 -                                  ])
    6.45 -        else:
    6.46 -            print "unknown argument %s" % sys.argv[idx]
    6.47 -            usage()
    6.48 -
    6.49 -    if len(decision_args) != 2:
    6.50 -        print "too many arguments"
    6.51 -        usage()
    6.52 -
    6.53 -    print get_decision(decision_args[0], decision_args[1])
    6.54 -
    6.55 -except ACMError:
    6.56 -	pass
    6.57 -except:
    6.58 -    traceback.print_exc(limit=1)
     7.1 --- a/tools/security/secpol_xml2bin.c	Tue Jun 13 15:33:10 2006 +0100
     7.2 +++ b/tools/security/secpol_xml2bin.c	Tue Jun 13 15:38:58 2006 +0100
     7.3 @@ -44,6 +44,8 @@
     7.4  
     7.5  #define DEBUG    0
     7.6  
     7.7 +#define NULL_LABEL_NAME "__NULL_LABEL__"
     7.8 +
     7.9  /* primary / secondary policy component setting */
    7.10  enum policycomponent { CHWALL, STE, NULLPOLICY }
    7.11      primary = NULLPOLICY, secondary = NULLPOLICY;
    7.12 @@ -467,7 +469,7 @@ int init_ssid_queues(void)
    7.13          return -ENOMEM;
    7.14  
    7.15      /* default chwall ssid */
    7.16 -    default_ssid_chwall->name = "DEFAULT";
    7.17 +    default_ssid_chwall->name = NULL_LABEL_NAME;
    7.18      default_ssid_chwall->num = max_chwall_ssids++;
    7.19      default_ssid_chwall->is_ref = 0;
    7.20      default_ssid_chwall->type = ANY;
    7.21 @@ -484,7 +486,7 @@ int init_ssid_queues(void)
    7.22      max_chwall_labels++;
    7.23  
    7.24      /* default ste ssid */
    7.25 -    default_ssid_ste->name = "DEFAULT";
    7.26 +    default_ssid_ste->name = NULL_LABEL_NAME;
    7.27      default_ssid_ste->num = max_ste_ssids++;
    7.28      default_ssid_ste->is_ref = 0;
    7.29      default_ssid_ste->type = ANY;