* [PATCH] xsm: add device tree labeling support
@ 2015-03-12 17:13 Daniel De Graaf
2015-03-12 17:53 ` Daniel De Graaf
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Daniel De Graaf @ 2015-03-12 17:13 UTC (permalink / raw)
To: xen-devel; +Cc: Daniel De Graaf, julien.grall
This adds support in the hypervisor and policy build toolchain for
Xen/Flask policy version 25, which adds the ability to label ARM device
tree nodes and expands the IOMEM ocontext entries to 64 bits.
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
Note: Actually using the features added in this patch requires a patch
to the SELinux toolchain (checkpolicy) which has just been sent to that
upstream and xen-devel.
tools/flask/policy/Makefile | 22 +++++---
xen/include/public/xsm/flask_op.h | 9 ++++
xen/xsm/flask/flask_op.c | 28 ++++++++++
xen/xsm/flask/include/security.h | 9 +++-
xen/xsm/flask/ss/policydb.c | 73 +++++++++++++++++++------
xen/xsm/flask/ss/policydb.h | 7 +--
xen/xsm/flask/ss/services.c | 111 +++++++++++++++++++++++++++++++++++---
7 files changed, 226 insertions(+), 33 deletions(-)
diff --git a/tools/flask/policy/Makefile b/tools/flask/policy/Makefile
index e564396..3220f6b 100644
--- a/tools/flask/policy/Makefile
+++ b/tools/flask/policy/Makefile
@@ -26,15 +26,13 @@ M4 ?= m4
#
########################################
-# Policy version
-# By default, checkpolicy creates the highest version policy it supports. Force
-# the use of version 24 which is the highest that Xen supports, and the first to
-# include the Xen policy type (needed for static device policy).
-OUTPUT_POLICY = 24
-
POLICY_FILENAME = xenpolicy-$(shell $(MAKE) -C $(XEN_ROOT)/xen xenversion --no-print-directory)
POLICY_LOADPATH = /boot
+# Minimum and maximum policy versions supported by the hypervisor
+POLICY_VER_MIN = 24
+POLICY_VER_MAX = 25
+
# policy source layout
POLDIR := policy
MODDIR := $(POLDIR)/modules
@@ -64,6 +62,18 @@ MOD_CONF := $(POLDIR)/modules.conf
# checkpolicy can use the #line directives provided by -s for error reporting:
M4PARAM := -D self_contained_policy -s
+
+# If checkpolicy supports Xen policy versions other than 24 (the first version
+# with support for the Xen policy), it will report them in the output of
+# "checkpolicy -t Xen -V", such as "Xen policy compatibility range: 24 25".
+# Otherwise, the maximum version supported by checkpolicy is 24.
+CHECKPOLICY_VERS_TXT := $(shell $(CHECKPOLICY) -t Xen -V)
+CHECKPOLICY_XEN_MAX = $(if $(findstring Xen,$(CHECKPOLICY_VERS_TXT)),$(lastword $(CHECKPOLICY_VERS_TXT)),24)
+
+# The output policy version used will be the highest supported by both the
+# hypervisor and the checkpolicy binary
+OUTPUT_POLICY := $(shell if test $(CHECKPOLICY_XEN_MAX) -gt $(POLICY_VER_MAX); then echo $(POLICY_VER_MAX); else echo $(CHECKPOLICY_XEN_MAX); fi)
+
CHECKPOLICY_PARAM := -t Xen -c $(OUTPUT_POLICY)
# enable MLS if requested.
diff --git a/xen/include/public/xsm/flask_op.h b/xen/include/public/xsm/flask_op.h
index f874589..c76359c 100644
--- a/xen/include/public/xsm/flask_op.h
+++ b/xen/include/public/xsm/flask_op.h
@@ -150,6 +150,13 @@ struct xen_flask_relabel {
uint32_t sid;
};
+struct xen_flask_devicetree_label {
+ /* IN */
+ uint32_t sid;
+ uint32_t length;
+ XEN_GUEST_HANDLE(char) path;
+};
+
struct xen_flask_op {
uint32_t cmd;
#define FLASK_LOAD 1
@@ -176,6 +183,7 @@ struct xen_flask_op {
#define FLASK_DEL_OCONTEXT 22
#define FLASK_GET_PEER_SID 23
#define FLASK_RELABEL_DOMAIN 24
+#define FLASK_DEVICETREE_LABEL 25
uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */
union {
struct xen_flask_load load;
@@ -195,6 +203,7 @@ struct xen_flask_op {
struct xen_flask_ocontext ocontext;
struct xen_flask_peersid peersid;
struct xen_flask_relabel relabel;
+ struct xen_flask_devicetree_label devicetree_label;
} u;
};
typedef struct xen_flask_op xen_flask_op_t;
diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
index 84c7fec..47aacc1 100644
--- a/xen/xsm/flask/flask_op.c
+++ b/xen/xsm/flask/flask_op.c
@@ -563,6 +563,27 @@ static int flask_security_load(struct xen_flask_load *load)
return ret;
}
+static int flask_devicetree_label(struct xen_flask_devicetree_label *arg)
+{
+ int rv;
+ char *buf;
+ u32 sid = arg->sid;
+ u32 perm = sid ? SECURITY__ADD_OCONTEXT : SECURITY__DEL_OCONTEXT;
+
+ rv = domain_has_security(current->domain, perm);
+ if ( rv )
+ return rv;
+
+ rv = flask_copyin_string(arg->path, &buf, arg->length, PAGE_SIZE);
+ if ( rv )
+ return rv;
+
+ /* buf is consumed or freed by this function */
+ rv = security_devicetree_setlabel(buf, sid);
+
+ return rv;
+}
+
#ifndef COMPAT
static int flask_ocontext_del(struct xen_flask_ocontext *arg)
@@ -790,6 +811,10 @@ ret_t do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op)
rv = flask_relabel_domain(&op.u.relabel);
break;
+ case FLASK_DEVICETREE_LABEL:
+ rv = flask_devicetree_label(&op.u.devicetree_label);
+ break;
+
default:
rv = -ENOSYS;
}
@@ -848,6 +873,9 @@ CHECK_flask_transition;
#define flask_security_get_bool compat_security_get_bool
#define flask_security_set_bool compat_security_set_bool
+#define xen_flask_devicetree_label compat_flask_devicetree_label
+#define flask_devicetree_label compat_devicetree_label
+
#define xen_flask_op_t compat_flask_op_t
#undef ret_t
#define ret_t int
diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h
index d07bae0..9590dd3 100644
--- a/xen/xsm/flask/include/security.h
+++ b/xen/xsm/flask/include/security.h
@@ -30,10 +30,11 @@
#define POLICYDB_VERSION_POLCAP 22
#define POLICYDB_VERSION_PERMISSIVE 23
#define POLICYDB_VERSION_BOUNDARY 24
+#define POLICYDB_VERSION_AARCH 25
/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AARCH
enum flask_bootparam_t {
FLASK_BOOTPARAM_PERMISSIVE,
@@ -82,6 +83,8 @@ int security_ioport_sid(u32 ioport, u32 *out_sid);
int security_device_sid(u32 device, u32 *out_sid);
+int security_devicetree_sid(const char *path, u32 *out_sid);
+
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass);
@@ -96,5 +99,7 @@ int security_iterate_ioport_sids(u32 start, u32 end,
int security_ocontext_add(u32 ocontext, unsigned long low,
unsigned long high, u32 sid);
-int security_ocontext_del(u32 ocontext, unsigned int low, unsigned int high);
+int security_ocontext_del(u32 ocontext, unsigned long low, unsigned long high);
+
+int security_devicetree_setlabel(char *path, u32 sid);
#endif /* _FLASK_SECURITY_H_ */
diff --git a/xen/xsm/flask/ss/policydb.c b/xen/xsm/flask/ss/policydb.c
index b88ea56..c7d29bd 100644
--- a/xen/xsm/flask/ss/policydb.c
+++ b/xen/xsm/flask/ss/policydb.c
@@ -74,55 +74,55 @@ static struct policydb_compat_info policydb_compat[] = {
{
.version = POLICYDB_VERSION_BASE,
.sym_num = SYM_NUM - 3,
- .ocon_num = OCON_NUM - 1,
+ .ocon_num = 4,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_BOOL,
.sym_num = SYM_NUM - 2,
- .ocon_num = OCON_NUM - 1,
+ .ocon_num = 4,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_IPV6,
.sym_num = SYM_NUM - 2,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_NLCLASS,
.sym_num = SYM_NUM - 2,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_MLS,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_AVTAB,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_RANGETRANS,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_POLCAP,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
.version = POLICYDB_VERSION_PERMISSIVE,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = 5,
.target_type = TARGET_XEN_OLD,
},
{
@@ -134,7 +134,13 @@ static struct policydb_compat_info policydb_compat[] = {
{
.version = POLICYDB_VERSION_BOUNDARY,
.sym_num = SYM_NUM,
- .ocon_num = OCON_NUM,
+ .ocon_num = OCON_DEVICE + 1,
+ .target_type = TARGET_XEN,
+ },
+ {
+ .version = POLICYDB_VERSION_AARCH,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_DTREE + 1,
.target_type = TARGET_XEN,
},
};
@@ -634,7 +640,7 @@ static void ocontext_destroy(struct ocontext *c, int i)
{
context_destroy(&c->context[0]);
context_destroy(&c->context[1]);
- if ( i == OCON_ISID )
+ if ( i == OCON_ISID || i == OCON_DTREE )
xfree(c->u.name);
xfree(c);
}
@@ -1999,11 +2005,23 @@ int policydb_read(struct policydb *p, void *fp)
"Old xen policy does not support iomemcon");
goto bad;
}
- rc = next_entry(buf, fp, sizeof(u32) *2);
- if ( rc < 0 )
- goto bad;
- c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
- c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
+ if ( p->policyvers >= POLICYDB_VERSION_AARCH )
+ {
+ u64 b64[2];
+ rc = next_entry(b64, fp, sizeof(u64) *2);
+ if ( rc < 0 )
+ goto bad;
+ c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
+ c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
+ }
+ else
+ {
+ rc = next_entry(buf, fp, sizeof(u32) *2);
+ if ( rc < 0 )
+ goto bad;
+ c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
+ c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
+ }
rc = context_read_and_validate(&c->context[0], p, fp);
if ( rc )
goto bad;
@@ -2023,6 +2041,29 @@ int policydb_read(struct policydb *p, void *fp)
if ( rc )
goto bad;
break;
+ case OCON_DTREE:
+ if ( p->target_type != TARGET_XEN )
+ {
+ printk(KERN_ERR
+ "Old xen policy does not support devicetreecon");
+ goto bad;
+ }
+ rc = next_entry(buf, fp, sizeof(u32));
+ if ( rc < 0 )
+ goto bad;
+ len = le32_to_cpu(buf[0]);
+ rc = -ENOMEM;
+ c->u.name = xmalloc_array(char, len + 1);
+ if (!c->u.name)
+ goto bad;
+ rc = next_entry(c->u.name, fp, len);
+ if ( rc < 0 )
+ goto bad;
+ c->u.name[len] = 0;
+ rc = context_read_and_validate(&c->context[0], p, fp);
+ if ( rc )
+ goto bad;
+ break;
default:
printk(KERN_ERR
"Flask: unsupported object context config data\n");
diff --git a/xen/xsm/flask/ss/policydb.h b/xen/xsm/flask/ss/policydb.h
index b176300..30be71a 100644
--- a/xen/xsm/flask/ss/policydb.h
+++ b/xen/xsm/flask/ss/policydb.h
@@ -154,8 +154,8 @@ struct ocontext {
u32 high_ioport;
} ioport;
struct {
- u32 low_iomem;
- u32 high_iomem;
+ u64 low_iomem;
+ u64 high_iomem;
} iomem;
} u;
struct context context[2]; /* security context(s) */
@@ -180,7 +180,8 @@ struct ocontext {
#define OCON_IOPORT 2 /* io ports */
#define OCON_IOMEM 3 /* io memory */
#define OCON_DEVICE 4 /* pci devices */
-#define OCON_NUM 5
+#define OCON_DTREE 5 /* device tree nodes */
+#define OCON_NUM 6
#define OCON_NUM_OLD 7
/* The policy database */
diff --git a/xen/xsm/flask/ss/services.c b/xen/xsm/flask/ss/services.c
index f0e459a..ba2336e 100644
--- a/xen/xsm/flask/ss/services.c
+++ b/xen/xsm/flask/ss/services.c
@@ -1831,6 +1831,41 @@ out:
return rc;
}
+int security_devicetree_sid(const char *path, u32 *out_sid)
+{
+ struct ocontext *c;
+ int rc = 0;
+
+ POLICY_RDLOCK;
+
+ c = policydb.ocontexts[OCON_DTREE];
+ while ( c )
+ {
+ if ( strcmp(c->u.name, path) == 0 )
+ break;
+ c = c->next;
+ }
+
+ if ( c )
+ {
+ if ( !c->sid[0] )
+ {
+ rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
+ if ( rc )
+ goto out;
+ }
+ *out_sid = c->sid[0];
+ }
+ else
+ {
+ *out_sid = SECINITSID_DEVICE;
+ }
+
+out:
+ POLICY_RDUNLOCK;
+ return rc;
+}
+
int security_find_bool(const char *name)
{
int i, rv = -ENOENT;
@@ -2131,7 +2166,7 @@ int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
c->u.iomem.high_iomem == high && c->sid[0] == sid)
break;
- printk("%s: IO Memory overlap with entry %#x - %#x\n",
+ printk("%s: IO Memory overlap with entry %#lx - %#lx\n",
__FUNCTION__, c->u.iomem.low_iomem,
c->u.iomem.high_iomem);
ret = -EEXIST;
@@ -2188,7 +2223,7 @@ int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
return ret;
}
-int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
+int security_ocontext_del( u32 ocon, unsigned long low, unsigned long high )
{
int ret = 0;
struct ocontext *c, *before_c;
@@ -2217,7 +2252,7 @@ int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
}
}
- printk("%s: ocontext not found: pirq %d\n", __FUNCTION__, low);
+ printk("%s: ocontext not found: pirq %ld\n", __FUNCTION__, low);
ret = -ENOENT;
break;
@@ -2243,7 +2278,7 @@ int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
}
}
- printk("%s: ocontext not found: ioport %#x - %#x\n", __FUNCTION__,
+ printk("%s: ocontext not found: ioport %#lx - %#lx\n", __FUNCTION__,
low, high);
ret = -ENOENT;
break;
@@ -2270,7 +2305,7 @@ int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
}
}
- printk("%s: ocontext not found: iomem %#x - %#x\n", __FUNCTION__,
+ printk("%s: ocontext not found: iomem %#lx - %#lx\n", __FUNCTION__,
low, high);
ret = -ENOENT;
break;
@@ -2296,7 +2331,7 @@ int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
}
}
- printk("%s: ocontext not found: pcidevice %#x\n", __FUNCTION__, low);
+ printk("%s: ocontext not found: pcidevice %#lx\n", __FUNCTION__, low);
ret = -ENOENT;
break;
@@ -2308,3 +2343,67 @@ int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
POLICY_WRUNLOCK;
return ret;
}
+
+int security_devicetree_setlabel(char *path, u32 sid)
+{
+ int ret = 0;
+ struct ocontext *c;
+ struct ocontext **pcurr;
+ struct ocontext *add = NULL;
+
+ if ( sid )
+ {
+ add = xzalloc(struct ocontext);
+ if ( add == NULL )
+ {
+ xfree(path);
+ return -ENOMEM;
+ }
+ add->sid[0] = sid;
+ add->u.name = path;
+ }
+ else
+ {
+ ret = -ENOENT;
+ }
+
+ POLICY_WRLOCK;
+
+ pcurr = &policydb.ocontexts[OCON_DTREE];
+ c = *pcurr;
+ while ( c )
+ {
+ if ( strcmp(c->u.name, path) == 0 )
+ {
+ if ( sid )
+ {
+ ret = -EEXIST;
+ break;
+ }
+ else
+ {
+ *pcurr = c->next;
+ xfree(c->u.name);
+ xfree(c);
+ ret = 0;
+ break;
+ }
+ }
+ pcurr = &c->next;
+ c = *pcurr;
+ }
+
+ if ( add && ret == 0 )
+ {
+ add->next = policydb.ocontexts[OCON_DTREE];
+ policydb.ocontexts[OCON_DTREE] = add;
+ add = NULL;
+ path = NULL;
+ }
+
+ POLICY_WRUNLOCK;
+
+ xfree(add);
+ xfree(path);
+ return ret;
+}
--
2.1.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] xsm: add device tree labeling support
2015-03-12 17:13 [PATCH] xsm: add device tree labeling support Daniel De Graaf
@ 2015-03-12 17:53 ` Daniel De Graaf
2015-03-12 18:09 ` Julien Grall
2015-03-12 18:17 ` Julien Grall
2 siblings, 0 replies; 4+ messages in thread
From: Daniel De Graaf @ 2015-03-12 17:53 UTC (permalink / raw)
To: xen-devel; +Cc: julien.grall
On 03/12/2015 01:13 PM, Daniel De Graaf wrote:
> This adds support in the hypervisor and policy build toolchain for
> Xen/Flask policy version 25, which adds the ability to label ARM device
> tree nodes and expands the IOMEM ocontext entries to 64 bits.
>
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> ---
>
> Note: Actually using the features added in this patch requires a patch
> to the SELinux toolchain (checkpolicy) which has just been sent to that
> upstream and xen-devel.
This patch will need to be reworked to support policy version 30 instead,
which will need additional logic to ignore the new fields added to the
security policy in versions 25-29. Please do not apply.
--
Daniel De Graaf
National Security Agency
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] xsm: add device tree labeling support
2015-03-12 17:13 [PATCH] xsm: add device tree labeling support Daniel De Graaf
2015-03-12 17:53 ` Daniel De Graaf
@ 2015-03-12 18:09 ` Julien Grall
2015-03-12 18:17 ` Julien Grall
2 siblings, 0 replies; 4+ messages in thread
From: Julien Grall @ 2015-03-12 18:09 UTC (permalink / raw)
To: Daniel De Graaf, xen-devel
Hi Daniel,
On 12/03/15 17:13, Daniel De Graaf wrote:
> This adds support in the hypervisor and policy build toolchain for
> Xen/Flask policy version 25, which adds the ability to label ARM device
> tree nodes and expands the IOMEM ocontext entries to 64 bits.
>
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> ---
>
> Note: Actually using the features added in this patch requires a patch
> to the SELinux toolchain (checkpolicy) which has just been sent to that
> upstream and xen-devel.
I will give a try to use it with my device tree passthrough series.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] xsm: add device tree labeling support
2015-03-12 17:13 [PATCH] xsm: add device tree labeling support Daniel De Graaf
2015-03-12 17:53 ` Daniel De Graaf
2015-03-12 18:09 ` Julien Grall
@ 2015-03-12 18:17 ` Julien Grall
2 siblings, 0 replies; 4+ messages in thread
From: Julien Grall @ 2015-03-12 18:17 UTC (permalink / raw)
To: Daniel De Graaf, xen-devel
Hi Daniel,
On 12/03/15 17:13, Daniel De Graaf wrote:
> int security_find_bool(const char *name)
> {
> int i, rv = -ENOENT;
> @@ -2131,7 +2166,7 @@ int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
> c->u.iomem.high_iomem == high && c->sid[0] == sid)
> break;
>
> - printk("%s: IO Memory overlap with entry %#x - %#x\n",
> + printk("%s: IO Memory overlap with entry %#lx - %#lx\n",
I had to replace %#lx by %#PRIx64 in order to make compile on ARM
services.c: In function ‘security_ocontext_add’:
services.c:2171:20: error: format ‘%lx’ expects argument of type ‘long
unsigned int’, but argument 3 has type ‘u64’ [-Werror=format=]
c->u.iomem.high_iomem);
^
services.c:2171:20: error: format ‘%lx’ expects argument of type ‘long
unsigned int’, but argument 4 has type ‘u64’ [-Werror=format=]
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-03-12 18:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-12 17:13 [PATCH] xsm: add device tree labeling support Daniel De Graaf
2015-03-12 17:53 ` Daniel De Graaf
2015-03-12 18:09 ` Julien Grall
2015-03-12 18:17 ` Julien Grall
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.