[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] This patch:
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0161d68cff37964498c29c24df1e27039b53b0c9 # Parent c76a8c8b7132bf2c20c1a269739c25bd7fdccbff This patch: * adds a get_ssid ACM command that allows privileged domains to retrieve types for either a given ssid reference or a given domain id (of a running domain); this command can be used to extend access control into device domains, e.g., to control network traffic currently moving through Domain 0 uncontrolled by the ACM policy * adds a script getlabel.sh that allows users inside Dom0 to retrieve the label for a given ssid reference or a given domain id (multiple labels might map onto a single ssid reference) * cleans up label-related code in tools/security by merging common functions into labelfuncs.sh * cleans up ACM code related to above changes (eventually approximating a common coding style) Signed-off-by Reiner Sailer <sailer@xxxxxxxxxx> Signed-off by Stefan Berger <stefanb@xxxxxxxxxx> diff -r c76a8c8b7132 -r 0161d68cff37 tools/security/Makefile --- a/tools/security/Makefile Fri Sep 2 07:55:45 2005 +++ b/tools/security/Makefile Fri Sep 2 07:59:12 2005 @@ -45,6 +45,7 @@ $(MAKE) secpol_xml2bin chmod 700 ./setlabel.sh chmod 700 ./updategrub.sh + chmod 700 ./getlabel.sh secpol_tool : secpol_tool.c secpol_compat.h $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< diff -r c76a8c8b7132 -r 0161d68cff37 tools/security/secpol_tool.c --- a/tools/security/secpol_tool.c Fri Sep 2 07:55:45 2005 +++ b/tools/security/secpol_tool.c Fri Sep 2 07:59:12 2005 @@ -25,6 +25,7 @@ #include <stdio.h> #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> @@ -40,6 +41,17 @@ #define PERROR(_m, _a...) \ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ errno, strerror(errno)) + +void usage(char *progname) +{ + printf("Use: %s \n" + "\t getpolicy\n" + "\t dumpstats\n" + "\t loadpolicy <binary policy file>\n" + "\t getssid -d <domainid> [-f]\n" + "\t getssid -s <ssidref> [-f]\n", progname); + exit(-1); +} static inline int do_policycmd(int xc_handle, unsigned int cmd, unsigned long data) @@ -320,7 +332,7 @@ if (ret) printf - ("ERROR setting policy. Use 'xm dmesg' to see details.\n"); + ("ERROR setting policy. Try 'xm dmesg' to see details.\n"); else printf("Successfully changed policy.\n"); @@ -370,7 +382,7 @@ if (ret < 0) { - printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); + printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n"); return ret; } stats = (struct acm_stats_buffer *) stats_buffer; @@ -421,17 +433,121 @@ } return ret; } +/************************ get ssidref & types ******************************/ +/* + * the ssid (types) can be looked up either by domain id or by ssidref + */ +int acm_domain_getssid(int xc_handle, int argc, char * const argv[]) +{ + /* this includes header and a set of types */ + #define MAX_SSIDBUFFER 2000 + int ret, i; + acm_op_t op; + struct acm_ssid_buffer *hdr; + unsigned char *buf; + int nice_print = 1; + + op.cmd = ACM_GETSSID; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getssid.get_ssid_by = UNSET; + /* arguments + -d ... domain id to look up + -s ... ssidref number to look up + -f ... formatted print (scripts depend on this format) + */ + while (1) + { + int c = getopt(argc, argv, "d:s:f"); + if (c == -1) + break; + if (c == 'd') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = DOMAINID; + op.u.getssid.id.domainid = strtoul(optarg, NULL, 0); + } + else if (c== 's') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = SSIDREF; + op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0); + } + else if (c== 'f') + { + nice_print = 0; + } + else + usage(argv[0]); + } + if (op.u.getssid.get_ssid_by == UNSET) + usage(argv[0]); + + buf = malloc(MAX_SSIDBUFFER); + if (!buf) + return -ENOMEM; + + /* dump it and then push it down into xen/acm */ + op.u.getssid.ssidbuf = buf; /* out */ + op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER; + ret = do_acm_op(xc_handle, &op); + + if (ret) + { + printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n"); + goto out; + } + hdr = (struct acm_ssid_buffer *)buf; + if (hdr->len > MAX_SSIDBUFFER) + { + printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n", + ret, hdr->len); + return -EIO; + } + if (nice_print) + { + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + printf(" P: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->primary_policy_code), hdr->primary_max_types); + printf(" Types: "); + for (i=0; i< hdr->primary_max_types; i++) + if (buf[hdr->primary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + + printf(" S: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->secondary_policy_code), hdr->secondary_max_types); + printf(" Types: "); + for (i=0; i< hdr->secondary_max_types; i++) + if (buf[hdr->secondary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + } + else + { + /* formatted print for use with scripts (.sh) + * update scripts when updating here (usually + * used in combination with -d to determine a + * running domain's label + */ + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + } + + /* return ste ssidref */ + if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) & 0xffff; + else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) >> 16; + out: + return ret; +} /***************************** main **************************************/ - -void usage(char *progname) -{ - printf("Use: %s \n" - "\t getpolicy\n" - "\t dumpstats\n" - "\t loadpolicy <binary policy file>\n", progname); - exit(-1); -} int main(int argc, char **argv) { @@ -459,6 +575,8 @@ if (argc != 2) usage(argv[0]); ret = acm_domain_dumpstats(acm_cmd_fd); + } else if (!strcmp(argv[1], "getssid")) { + ret = acm_domain_getssid(acm_cmd_fd, argc, argv); } else usage(argv[0]); diff -r c76a8c8b7132 -r 0161d68cff37 tools/security/setlabel.sh --- a/tools/security/setlabel.sh Fri Sep 2 07:55:45 2005 +++ b/tools/security/setlabel.sh Fri Sep 2 07:59:12 2005 @@ -34,275 +34,27 @@ exec sh -c "bash $0 $*" fi +export PATH=$PATH:. +source labelfuncs.sh usage () { - echo "Usage: $0 [Option] <vmfile> <label> <policy name> " - echo " or $0 -l <policy name>" + echo "Usage: $0 [Option] <vmfile> <label> [<policy name>]" + echo " or $0 -l [<policy name>]" echo "" - echo "Valid Options are:" + echo "Valid options are:" echo "-r : to relabel a file without being prompted" echo "" echo "vmfile : XEN vm configuration file" - echo "label : the label to map" + echo "label : the label to map to an ssidref" echo "policy name : the name of the policy, i.e. 'chwall'" + echo " If the policy name is omitted, it is attempted" + echo " to find the current policy's name in grub.conf." echo "" - echo "-l <policy name> is used to show valid labels in the map file" + echo "-l [<policy name>] is used to show valid labels in the map file of" + echo " the given or current policy." echo "" } - - -findMapFile () -{ - mapfile="./$1.map" - if [ -r "$mapfile" ]; then - return 1 - fi - - mapfile="./policies/$1/$1.map" - if [ -r "$mapfile" ]; then - return 1 - fi - - return 0 -} - -showLabels () -{ - mapfile=$1 - if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then - echo "Cannot read from vm configuration file $vmfile." - return -1 - fi - - getPrimaryPolicy $mapfile - getSecondaryPolicy $mapfile - - echo "The following labels are available:" - let line=1 - while [ 1 ]; do - ITEM=`cat $mapfile | \ - awk -vline=$line \ - -vprimary=$primary \ - '{ \ - if ($1 == "LABEL->SSID" && \ - $2 == "VM" && \ - $3 == primary ) { \ - ctr++; \ - if (ctr == line) { \ - print $4; \ - } \ - } \ - } END { \ - }'` - - if [ "$ITEM" == "" ]; then - break - fi - if [ "$secondary" != "NULL" ]; then - LABEL=`cat $mapfile | \ - awk -vitem=$ITEM \ - '{ - if ($1 == "LABEL->SSID" && \ - $2 == "VM" && \ - $3 == "CHWALL" && \ - $4 == item ) { \ - result = item; \ - } \ - } END { \ - print result \ - }'` - else - LABEL=$ITEM - fi - - if [ "$LABEL" != "" ]; then - echo "$LABEL" - found=1 - fi - let line=line+1 - done - if [ "$found" != "1" ]; then - echo "No labels found." - fi -} - -getPrimaryPolicy () -{ - mapfile=$1 - primary=`cat $mapfile | \ - awk ' \ - { \ - if ( $1 == "PRIMARY" ) { \ - res=$2; \ - } \ - } END { \ - print res; \ - } '` -} - -getSecondaryPolicy () -{ - mapfile=$1 - secondary=`cat $mapfile | \ - awk ' \ - { \ - if ( $1 == "SECONDARY" ) { \ - res=$2; \ - } \ - } END { \ - print res; \ - } '` -} - - -getDefaultSsid () -{ - mapfile=$1 - pol=$2 - RES=`cat $mapfile \ - awk -vpol=$pol \ - { \ - if ($1 == "LABEL->SSID" && \ - $2 == "ANY" && \ - $3 == pol && \ - $4 == "DEFAULT" ) {\ - res=$5; \ - } \ - } END { \ - printf "%04x", strtonum(res) \ - }'` - echo "default NULL mapping is $RES" - defaultssid=$RES -} - -relabel () -{ - vmfile=$1 - label=$2 - mapfile=$3 - mode=$4 - - if [ ! -r "$vmfile" ]; then - echo "Cannot read from vm configuration file $vmfile." - return -1 - fi - - if [ ! -w "$vmfile" ]; then - echo "Cannot write to vm configuration file $vmfile." - return -1 - fi - - if [ ! -r "$mapfile" ] ; then - echo "Cannot read mapping file $mapfile." - return -1 - fi - - # Determine which policy is primary, which sec. - getPrimaryPolicy $mapfile - getSecondaryPolicy $mapfile - - # Calculate the primary policy's SSIDREF - if [ "$primary" == "NULL" ]; then - SSIDLO="0000" - else - SSIDLO=`cat $mapfile | \ - awk -vlabel=$label \ - -vprimary=$primary \ - '{ \ - if ( $1 == "LABEL->SSID" && \ - $2 == "VM" && \ - $3 == primary && \ - $4 == label ) { \ - result=$5 \ - } \ - } END { \ - if (result != "" ) \ - {printf "%04x", strtonum(result)}\ - }'` - fi - - # Calculate the secondary policy's SSIDREF - if [ "$secondary" == "NULL" ]; then - SSIDHI="0000" - else - SSIDHI=`cat $mapfile | \ - awk -vlabel=$label \ - -vsecondary=$secondary \ - '{ \ - if ( $1 == "LABEL->SSID" && \ - $2 == "VM" && \ - $3 == secondary && \ - $4 == label ) { \ - result=$5 \ - } \ - } END { \ - if (result != "" ) \ - {printf "%04x", strtonum(result)}\ - }'` - fi - - if [ "$SSIDLO" == "" -o \ - "$SSIDHI" == "" ]; then - echo "Could not map the given label '$label'." - return -1 - fi - - ACM_POLICY=`cat $mapfile | \ - awk ' { if ( $1 == "POLICY" ) { \ - result=$2 \ - } \ - } \ - END { \ - if (result != "") { \ - printf result \ - } \ - }'` - - if [ "$ACM_POLICY" == "" ]; then - echo "Could not find 'POLICY' entry in map file." - return -1 - fi - - SSIDREF="0x$SSIDHI$SSIDLO" - - if [ "$mode" != "relabel" ]; then - RES=`cat $vmfile | \ - awk '{ \ - if ( substr($1,0,7) == "ssidref" ) {\ - print $0; \ - } \ - }'` - if [ "$RES" != "" ]; then - echo "Do you want to overwrite the existing mapping ($RES)? (y/N)" - read user - if [ "$user" != "y" -a "$user" != "Y" ]; then - echo "Aborted." - return 0 - fi - fi - fi - - #Write the output - vmtmp1="/tmp/__setlabel.tmp1" - vmtmp2="/tmp/__setlabel.tmp2" - touch $vmtmp1 - touch $vmtmp2 - if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then - echo "Cannot create temporary files. Aborting." - return -1 - fi - RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1` - RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2` - RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1` - echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1 - echo "#ACM_LABEL=$label" >> $vmtmp1 - echo "ssidref = $SSIDREF" >> $vmtmp1 - mv -f $vmtmp1 $vmfile - rm -rf $vmtmp1 $vmtmp2 - echo "Mapped label '$label' to ssidref '$SSIDREF'." -} - if [ "$1" == "-r" ]; then @@ -317,10 +69,25 @@ if [ "$mode" == "show" ]; then if [ "$1" == "" ]; then - usage - exit -1; + findGrubConf + ret=$? + if [ $ret -eq 0 ]; then + echo "Could not find grub.conf" + exit -1; + fi + findPolicyInGrub $grubconf + if [ "$policy" != "" ]; then + echo "Assuming policy to be '$policy'."; + else + echo "Could not find policy." + exit -1; + fi + else + policy=$3; fi - findMapFile $1 + + + findMapFile $policy res=$? if [ "$res" != "0" ]; then showLabels $mapfile @@ -330,11 +97,29 @@ elif [ "$mode" == "usage" ]; then usage else + if [ "$2" == "" ]; then + usage + exit -1 + fi if [ "$3" == "" ]; then - usage - exit -1; + findGrubConf + ret=$? + if [ $ret -eq 0 ]; then + echo "Could not find grub.conf" + exit -1; + fi + findPolicyInGrub $grubconf + if [ "$policy" != "" ]; then + echo "Assuming policy to be '$policy'."; + else + echo "Could not find policy." + exit -1; + fi + + else + policy=$3; fi - findMapFile $3 + findMapFile $policy res=$? if [ "$res" != "0" ]; then relabel $1 $2 $mapfile $mode diff -r c76a8c8b7132 -r 0161d68cff37 xen/acm/acm_chinesewall_hooks.c --- a/xen/acm/acm_chinesewall_hooks.c Fri Sep 2 07:55:45 2005 +++ b/xen/acm/acm_chinesewall_hooks.c Fri Sep 2 07:59:12 2005 @@ -310,6 +310,28 @@ return 0; } +static int +chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) +{ + int i; + + /* fill in buffer */ + if (chwall_bin_pol.max_types > len) + return -EFAULT; + + if (ssidref >= chwall_bin_pol.max_ssidrefs) + return -EFAULT; + + /* read types for chwall ssidref */ + for(i=0; i< chwall_bin_pol.max_types; i++) { + if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i]) + buf[i] = 1; + else + buf[i] = 0; + } + return chwall_bin_pol.max_types; +} + /*************************** * Authorization functions ***************************/ @@ -492,6 +514,7 @@ .dump_binary_policy = chwall_dump_policy, .set_binary_policy = chwall_set_policy, .dump_statistics = chwall_dump_stats, + .dump_ssid_types = chwall_dump_ssid_types, /* domain management control hooks */ .pre_domain_create = chwall_pre_domain_create, .post_domain_create = chwall_post_domain_create, diff -r c76a8c8b7132 -r 0161d68cff37 xen/acm/acm_core.c --- a/xen/acm/acm_core.c Fri Sep 2 07:55:45 2005 +++ b/xen/acm/acm_core.c Fri Sep 2 07:59:12 2005 @@ -64,16 +64,17 @@ void acm_set_endian(void) { u32 test = 1; - if (*((u8 *)&test) == 1) { + if (*((u8 *)&test) == 1) + { printk("ACM module running in LITTLE ENDIAN.\n"); - little_endian = 1; - } else { - printk("ACM module running in BIG ENDIAN.\n"); - little_endian = 0; - } -} - -#if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) + little_endian = 1; + } + else + { + printk("ACM module running in BIG ENDIAN.\n"); + little_endian = 0; + } +} /* initialize global security policy for Xen; policy write-locked already */ static void @@ -101,7 +102,8 @@ * Try all modules and see whichever could be the binary policy. * Adjust the initrdidx if module[1] is the binary policy. */ - for (i = mbi->mods_count-1; i >= 1; i--) { + for (i = mbi->mods_count-1; i >= 1; i--) + { struct acm_policy_buffer *pol; char *_policy_start; unsigned long _policy_len; @@ -117,23 +119,32 @@ continue; /* not a policy */ pol = (struct acm_policy_buffer *)_policy_start; - if (ntohl(pol->magic) == ACM_MAGIC) { + if (ntohl(pol->magic) == ACM_MAGIC) + { rc = acm_set_policy((void *)_policy_start, (u16)_policy_len, 0); - if (rc == ACM_OK) { + if (rc == ACM_OK) + { printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start); - if (i == 1) { - if (mbi->mods_count > 2) { + if (i == 1) + { + if (mbi->mods_count > 2) + { *initrdidx = 2; - } else { + } + else { *initrdidx = 0; } - } else { + } + else + { *initrdidx = 1; } break; - } else { + } + else + { printk("Invalid policy. %d.th module line.\n", i+1); } } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */ @@ -147,56 +158,84 @@ const multiboot_info_t *mbi, unsigned long initial_images_start) { - int ret = -EINVAL; - - acm_set_endian(); + int ret = ACM_OK; + + acm_set_endian(); write_lock(&acm_bin_pol_rwlock); - - if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) { - acm_init_binary_policy(NULL, NULL); - acm_init_chwall_policy(); + acm_init_binary_policy(NULL, NULL); + + /* set primary policy component */ + switch ((ACM_USE_SECURITY_POLICY) & 0x0f) + { + + case ACM_CHINESE_WALL_POLICY: + acm_init_chwall_policy(); acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; acm_primary_ops = &acm_chinesewall_ops; + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + acm_init_ste_policy(); + acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_primary_ops = &acm_simple_type_enforcement_ops; + break; + + default: + /* NULL or Unknown policy not allowed primary; + * NULL/NULL will not compile this code */ + ret = -EINVAL; + goto out; + } + + /* secondary policy component part */ + switch ((ACM_USE_SECURITY_POLICY) >> 4) { + case ACM_NULL_POLICY: acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; acm_secondary_ops = &acm_null_ops; - ret = ACM_OK; - } else if (ACM_USE_SECURITY_POLICY == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) { - acm_init_binary_policy(NULL, NULL); + break; + + case ACM_CHINESE_WALL_POLICY: + if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY) + { /* not a valid combination */ + ret = -EINVAL; + goto out; + } + acm_init_chwall_policy(); + acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY; + acm_secondary_ops = &acm_chinesewall_ops; + break; + + case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: + if (acm_bin_pol.primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + { /* not a valid combination */ + ret = -EINVAL; + goto out; + } acm_init_ste_policy(); - acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_primary_ops = &acm_simple_type_enforcement_ops; - acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; - acm_secondary_ops = &acm_null_ops; - ret = ACM_OK; - } else if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) { - acm_init_binary_policy(NULL, NULL); - acm_init_chwall_policy(); - acm_init_ste_policy(); - acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_primary_ops = &acm_chinesewall_ops; acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; acm_secondary_ops = &acm_simple_type_enforcement_ops; - ret = ACM_OK; - } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) { - acm_init_binary_policy(NULL, NULL); - acm_bin_pol.primary_policy_code = ACM_NULL_POLICY; - acm_primary_ops = &acm_null_ops; - acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; - acm_secondary_ops = &acm_null_ops; - ret = ACM_OK; + break; + + default: + ret = -EINVAL; + goto out; + } + + out: + write_unlock(&acm_bin_pol_rwlock); + + if (ret != ACM_OK) + { + printk("%s: Error setting policies.\n", __func__); + /* here one could imagine a clean panic */ + return -EINVAL; } - write_unlock(&acm_bin_pol_rwlock); - - if (ret != ACM_OK) - return -EINVAL; acm_setup(initrdidx, mbi, initial_images_start); printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, - ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); + ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), + ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); return ret; } - - -#endif int acm_init_domain_ssid(domid_t id, ssidref_t ssidref) @@ -205,7 +244,8 @@ struct domain *subj = find_domain_by_id(id); int ret1, ret2; - if (subj == NULL) { + if (subj == NULL) + { printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id); return ACM_NULL_POINTER_ERROR; } @@ -235,14 +275,16 @@ else ret2 = ACM_OK; - if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) { + if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) + { printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", __func__, subj->domain_id); acm_free_domain_ssid(ssid); put_domain(subj); return ACM_INIT_SSID_ERROR; } - printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref); + printk("%s: assigned domain %x the ssidref=%x.\n", + __func__, id, ssid->ssidref); put_domain(subj); return ACM_OK; } @@ -254,11 +296,12 @@ domid_t id; /* domain is already gone, just ssid is left */ - if (ssid == NULL) { + if (ssid == NULL) + { printk("%s: ACM_NULL_POINTER ERROR.\n", __func__); return ACM_NULL_POINTER_ERROR; } - id = ssid->domainid; + id = ssid->domainid; ssid->subject = NULL; if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ @@ -268,6 +311,7 @@ acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); ssid->secondary_ssid = NULL; xfree(ssid); - printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, id); + printkd("%s: Freed individual domain ssid (domain=%02x).\n", + __func__, id); return ACM_OK; } diff -r c76a8c8b7132 -r 0161d68cff37 xen/acm/acm_null_hooks.c --- a/xen/acm/acm_null_hooks.c Fri Sep 2 07:55:45 2005 +++ b/xen/acm/acm_null_hooks.c Fri Sep 2 07:59:12 2005 @@ -14,13 +14,13 @@ #include <acm/acm_hooks.h> static int -null_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) +null_init_domain_ssid(void **ssid, ssidref_t ssidref) { return ACM_OK; } static void -null_free_domain_ssid(void *chwall_ssid) +null_free_domain_ssid(void *ssid) { return; } @@ -44,6 +44,14 @@ return 0; } +static int +null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size) +{ + /* no types */ + return 0; +} + + /* now define the hook structure similarly to LSM */ struct acm_operations acm_null_ops = { .init_domain_ssid = null_init_domain_ssid, @@ -51,6 +59,7 @@ .dump_binary_policy = null_dump_binary_policy, .set_binary_policy = null_set_binary_policy, .dump_statistics = null_dump_stats, + .dump_ssid_types = null_dump_ssid_types, /* domain management control hooks */ .pre_domain_create = NULL, .post_domain_create = NULL, diff -r c76a8c8b7132 -r 0161d68cff37 xen/acm/acm_policy.c --- a/xen/acm/acm_policy.c Fri Sep 2 07:55:45 2005 +++ b/xen/acm/acm_policy.c Fri Sep 2 07:59:12 2005 @@ -26,8 +26,8 @@ #include <xen/lib.h> #include <xen/delay.h> #include <xen/sched.h> +#include <acm/acm_core.h> #include <public/acm_ops.h> -#include <acm/acm_core.h> #include <acm/acm_hooks.h> #include <acm/acm_endian.h> @@ -37,14 +37,16 @@ u8 *policy_buffer = NULL; struct acm_policy_buffer *pol; - if (buf_size < sizeof(struct acm_policy_buffer)) + if (buf_size < sizeof(struct acm_policy_buffer)) return -EFAULT; /* 1. copy buffer from domain */ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) - goto error_free; + return -ENOMEM; + if (isuserbuffer) { - if (copy_from_user(policy_buffer, buf, buf_size)) { + if (copy_from_user(policy_buffer, buf, buf_size)) + { printk("%s: Error copying!\n",__func__); goto error_free; } @@ -57,11 +59,13 @@ if ((ntohl(pol->magic) != ACM_MAGIC) || (ntohl(pol->policy_version) != ACM_POLICY_VERSION) || (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || - (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) { + (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) + { printkd("%s: Wrong policy magics or versions!\n", __func__); goto error_free; } - if (buf_size != ntohl(pol->len)) { + if (buf_size != ntohl(pol->len)) + { printk("%s: ERROR in buf size.\n", __func__); goto error_free; } @@ -72,27 +76,25 @@ /* 3. set primary policy data */ if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset), ntohl(pol->secondary_buffer_offset) - - ntohl(pol->primary_buffer_offset))) { + ntohl(pol->primary_buffer_offset))) goto error_lock_free; - } + /* 4. set secondary policy data */ if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), ntohl(pol->len) - - ntohl(pol->secondary_buffer_offset))) { + ntohl(pol->secondary_buffer_offset))) goto error_lock_free; - } + write_unlock(&acm_bin_pol_rwlock); - if (policy_buffer != NULL) - xfree(policy_buffer); + xfree(policy_buffer); return ACM_OK; error_lock_free: write_unlock(&acm_bin_pol_rwlock); error_free: printk("%s: Error setting policy.\n", __func__); - if (policy_buffer != NULL) - xfree(policy_buffer); - return -ENOMEM; + xfree(policy_buffer); + return -EFAULT; } int @@ -102,11 +104,14 @@ int ret; struct acm_policy_buffer *bin_pol; + if (buf_size < sizeof(struct acm_policy_buffer)) + return -EFAULT; + if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) return -ENOMEM; read_lock(&acm_bin_pol_rwlock); - /* future: read policy from file and set it */ + bin_pol = (struct acm_policy_buffer *)policy_buffer; bin_pol->magic = htonl(ACM_MAGIC); bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code); @@ -118,27 +123,30 @@ ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset), buf_size - ntohl(bin_pol->primary_buffer_offset)); - if (ret < 0) { - printk("%s: ERROR creating chwallpolicy buffer.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return -1; - } + if (ret < 0) + goto error_free_unlock; + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset), buf_size - ntohl(bin_pol->secondary_buffer_offset)); - if (ret < 0) { - printk("%s: ERROR creating chwallpolicy buffer.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return -1; - } + if (ret < 0) + goto error_free_unlock; + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - read_unlock(&acm_bin_pol_rwlock); if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) - return -EFAULT; + goto error_free_unlock; + + read_unlock(&acm_bin_pol_rwlock); xfree(policy_buffer); return ACM_OK; + + error_free_unlock: + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting policy.\n", __func__); + xfree(policy_buffer); + return -EFAULT; } int @@ -185,4 +193,62 @@ return -EFAULT; } + +int +acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size) +{ + /* send stats to user space */ + u8 *ssid_buffer; + int ret; + struct acm_ssid_buffer *acm_ssid; + if (buf_size < sizeof(struct acm_ssid_buffer)) + return -EFAULT; + + if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; + + read_lock(&acm_bin_pol_rwlock); + + acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; + acm_ssid->len = sizeof(struct acm_ssid_buffer); + acm_ssid->ssidref = ssidref; + acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; + acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; + acm_ssid->primary_types_offset = acm_ssid->len; + + /* ret >= 0 --> ret == max_types */ + ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref), + ssid_buffer + acm_ssid->primary_types_offset, + buf_size - acm_ssid->primary_types_offset); + if (ret < 0) + goto error_free_unlock; + + acm_ssid->len += ret; + acm_ssid->primary_max_types = ret; + + acm_ssid->secondary_types_offset = acm_ssid->len; + + ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref), + ssid_buffer + acm_ssid->secondary_types_offset, + buf_size - acm_ssid->secondary_types_offset); + if (ret < 0) + goto error_free_unlock; + + acm_ssid->len += ret; + acm_ssid->secondary_max_types = ret; + + if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) + goto error_free_unlock; + + read_unlock(&acm_bin_pol_rwlock); + xfree(ssid_buffer); + return ACM_OK; + + error_free_unlock: + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting ssid.\n", __func__); + xfree(ssid_buffer); + return -ENOMEM; +} + /*eof*/ diff -r c76a8c8b7132 -r 0161d68cff37 xen/acm/acm_simple_type_enforcement_hooks.c --- a/xen/acm/acm_simple_type_enforcement_hooks.c Fri Sep 2 07:55:45 2005 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c Fri Sep 2 07:59:12 2005 @@ -383,6 +383,27 @@ return sizeof(struct acm_ste_stats_buffer); } +static int +ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) +{ + int i; + + /* fill in buffer */ + if (ste_bin_pol.max_types > len) + return -EFAULT; + + if (ssidref >= ste_bin_pol.max_ssidrefs) + return -EFAULT; + + /* read types for chwall ssidref */ + for(i=0; i< ste_bin_pol.max_types; i++) { + if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) + buf[i] = 1; + else + buf[i] = 0; + } + return ste_bin_pol.max_types; +} /* we need to go through this before calling the hooks, * returns 1 == cache hit */ @@ -625,22 +646,23 @@ /* policy management services */ .init_domain_ssid = ste_init_domain_ssid, .free_domain_ssid = ste_free_domain_ssid, - .dump_binary_policy = ste_dump_policy, - .set_binary_policy = ste_set_policy, + .dump_binary_policy = ste_dump_policy, + .set_binary_policy = ste_set_policy, .dump_statistics = ste_dump_stats, + .dump_ssid_types = ste_dump_ssid_types, /* domain management control hooks */ .pre_domain_create = ste_pre_domain_create, - .post_domain_create = NULL, - .fail_domain_create = NULL, - .post_domain_destroy = ste_post_domain_destroy, + .post_domain_create = NULL, + .fail_domain_create = NULL, + .post_domain_destroy = ste_post_domain_destroy, /* event channel control hooks */ - .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, + .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, .fail_eventchannel_unbound = NULL, .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, .fail_eventchannel_interdomain = NULL, /* grant table control hooks */ - .pre_grant_map_ref = ste_pre_grant_map_ref, - .fail_grant_map_ref = NULL, - .pre_grant_setup = ste_pre_grant_setup, - .fail_grant_setup = NULL, + .pre_grant_map_ref = ste_pre_grant_map_ref, + .fail_grant_map_ref = NULL, + .pre_grant_setup = ste_pre_grant_setup, + .fail_grant_setup = NULL, }; diff -r c76a8c8b7132 -r 0161d68cff37 xen/common/acm_ops.c --- a/xen/common/acm_ops.c Fri Sep 2 07:55:45 2005 +++ b/xen/common/acm_ops.c Fri Sep 2 07:59:12 2005 @@ -19,6 +19,7 @@ #include <xen/types.h> #include <xen/lib.h> #include <xen/mm.h> +#include <public/acm.h> #include <public/acm_ops.h> #include <xen/sched.h> #include <xen/event.h> @@ -41,7 +42,8 @@ POLICY, /* access to policy interface (early drop) */ GETPOLICY, /* dump policy cache */ SETPOLICY, /* set policy cache (controls security) */ - DUMPSTATS /* dump policy statistics */ + DUMPSTATS, /* dump policy statistics */ + GETSSID /* retrieve ssidref for domain id */ } acm_operation_t; int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops) @@ -117,6 +119,35 @@ } break; + case ACM_GETSSID: + { + ssidref_t ssidref; + + if (acm_authorize_acm_ops(current->domain, GETSSID)) + return -EACCES; + + if (op->u.getssid.get_ssid_by == SSIDREF) + ssidref = op->u.getssid.id.ssidref; + else if (op->u.getssid.get_ssid_by == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); + if (!subj) + return -ESRCH; /* domain not found */ + + ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else + return -ESRCH; + + ret = acm_get_ssid(ssidref, + op->u.getssid.ssidbuf, + op->u.getssid.ssidbuf_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; + default: ret = -ESRCH; diff -r c76a8c8b7132 -r 0161d68cff37 xen/include/acm/acm_core.h --- a/xen/include/acm/acm_core.h Fri Sep 2 07:55:45 2005 +++ b/xen/include/acm/acm_core.h Fri Sep 2 07:59:12 2005 @@ -101,9 +101,15 @@ * primary ssidref = lower 16 bit * secondary ssidref = higher 16 bit */ +#define ACM_PRIMARY(ssidref) \ + ((ssidref) & 0xffff) + +#define ACM_SECONDARY(ssidref) \ + ((ssidref) >> 16) + #define GET_SSIDREF(POLICY, ssidref) \ ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ((ssidref) & 0xffff) : ((ssidref) >> 16) + ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) /* macros to access ssid pointer for primary / secondary policy */ #define GET_SSIDP(POLICY, ssid) \ @@ -116,6 +122,7 @@ int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer); int acm_get_policy(void *buf, u16 buf_size); int acm_dump_statistics(void *buf, u16 buf_size); +int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size); #endif diff -r c76a8c8b7132 -r 0161d68cff37 xen/include/acm/acm_hooks.h --- a/xen/include/acm/acm_hooks.h Fri Sep 2 07:55:45 2005 +++ b/xen/include/acm/acm_hooks.h Fri Sep 2 07:59:12 2005 @@ -92,6 +92,7 @@ int (*dump_binary_policy) (u8 *buffer, u16 buf_size); int (*set_binary_policy) (u8 *buffer, u16 buf_size); int (*dump_statistics) (u8 *buffer, u16 buf_size); + int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size); /* domain management control hooks (can be NULL) */ int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref); void (*post_domain_create) (domid_t domid, ssidref_t ssidref); diff -r c76a8c8b7132 -r 0161d68cff37 xen/include/public/acm.h --- a/xen/include/public/acm.h Fri Sep 2 07:55:45 2005 +++ b/xen/include/public/acm.h Fri Sep 2 07:59:12 2005 @@ -56,20 +56,22 @@ #define ACM_ACCESS_DENIED -111 #define ACM_NULL_POINTER_ERROR -200 -#define ACM_MAX_POLICY 3 - +/* primary policy in lower 4 bits */ #define ACM_NULL_POLICY 0 #define ACM_CHINESE_WALL_POLICY 1 #define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2 -#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3 + +/* combinations have secondary policy component in higher 4bit */ +#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \ + ((ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY << 4) | ACM_CHINESE_WALL_POLICY) /* policy: */ #define ACM_POLICY_NAME(X) \ - (X == ACM_NULL_POLICY) ? "NULL policy" : \ - (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \ - (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT policy" : \ - (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \ - "UNDEFINED policy" + ((X) == (ACM_NULL_POLICY)) ? "NULL policy" : \ + ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL policy" : \ + ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT policy" : \ + ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \ + "UNDEFINED policy" /* the following policy versions must be increased * whenever the interpretation of the related @@ -122,7 +124,7 @@ */ struct acm_policy_buffer { u32 policy_version; /* ACM_POLICY_VERSION */ - u32 magic; + u32 magic; u32 len; u32 primary_policy_code; u32 primary_buffer_offset; @@ -151,7 +153,7 @@ }; struct acm_stats_buffer { - u32 magic; + u32 magic; u32 len; u32 primary_policy_code; u32 primary_stats_offset; @@ -168,5 +170,15 @@ u32 gt_cachehit_count; }; +struct acm_ssid_buffer { + u32 len; + ssidref_t ssidref; + u32 primary_policy_code; + u32 primary_max_types; + u32 primary_types_offset; + u32 secondary_policy_code; + u32 secondary_max_types; + u32 secondary_types_offset; +}; #endif diff -r c76a8c8b7132 -r 0161d68cff37 xen/include/public/acm_ops.h --- a/xen/include/public/acm_ops.h Fri Sep 2 07:55:45 2005 +++ b/xen/include/public/acm_ops.h Fri Sep 2 07:59:12 2005 @@ -1,3 +1,4 @@ + /****************************************************************************** * acm_ops.h * @@ -27,7 +28,7 @@ * This makes sure that old versions of acm tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define ACM_INTERFACE_VERSION 0xAAAA0003 +#define ACM_INTERFACE_VERSION 0xAAAA0004 /************************************************************************/ @@ -46,12 +47,25 @@ u16 pullcache_size; } acm_getpolicy_t; + #define ACM_DUMPSTATS 6 typedef struct acm_dumpstats { void *pullcache; u16 pullcache_size; } acm_dumpstats_t; + +#define ACM_GETSSID 7 +enum get_type {UNSET, SSIDREF, DOMAINID}; +typedef struct acm_getssid { + enum get_type get_ssid_by; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id; + void *ssidbuf; + u16 ssidbuf_size; +} acm_getssid_t; typedef struct acm_op { u32 cmd; @@ -60,6 +74,7 @@ acm_setpolicy_t setpolicy; acm_getpolicy_t getpolicy; acm_dumpstats_t dumpstats; + acm_getssid_t getssid; } u; } acm_op_t; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |