# 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
|