summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDarrel Goeddel <dgoeddel@TrustedCS.com>2006-09-25 23:31:59 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 08:48:52 -0700
commitf3f8771420737004da55159c2f2dc0b6f483a4ef (patch)
tree01ff2aa4dc82cdc5b2383648f9fabb8378250d00 /security
parent016b9bdb81d9c9c7800e4e224ade38d8b37669d3 (diff)
downloadlinux-f3f8771420737004da55159c2f2dc0b6f483a4ef.tar.bz2
[PATCH] selinux: add support for range transitions on object classes
Introduces support for policy version 21. This version of the binary kernel policy allows for defining range transitions on security classes other than the process security class. As always, backwards compatibility for older formats is retained. The security class is read in as specified when using the new format, while the "process" security class is assumed when using an older policy format. Signed-off-by: Darrel Goeddel <dgoeddel@trustedcs.com> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: James Morris <jmorris@namei.org> Acked-by: Eric Paris <eparis@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/Kconfig2
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/mls.c21
-rw-r--r--security/selinux/ss/policydb.c27
-rw-r--r--security/selinux/ss/policydb.h7
5 files changed, 37 insertions, 23 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 5c64c746b062..293dbd6246c1 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
- range 15 20
+ range 15 21
default 19
help
This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index aa21ca1721af..1ef79172cc8c 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -24,13 +24,14 @@
#define POLICYDB_VERSION_VALIDATETRANS 19
#define POLICYDB_VERSION_MLS 19
#define POLICYDB_VERSION_AVTAB 20
+#define POLICYDB_VERSION_RANGETRANS 21
/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#else
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_RANGETRANS
#endif
extern int selinux_enabled;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 119bd6078ba1..c713af23250a 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -530,22 +530,21 @@ int mls_compute_sid(struct context *scontext,
u32 specified,
struct context *newcontext)
{
+ struct range_trans *rtr;
+
if (!selinux_mls_enabled)
return 0;
switch (specified) {
case AVTAB_TRANSITION:
- if (tclass == SECCLASS_PROCESS) {
- struct range_trans *rangetr;
- /* Look for a range transition rule. */
- for (rangetr = policydb.range_tr; rangetr;
- rangetr = rangetr->next) {
- if (rangetr->dom == scontext->type &&
- rangetr->type == tcontext->type) {
- /* Set the range from the rule */
- return mls_range_set(newcontext,
- &rangetr->range);
- }
+ /* Look for a range transition rule. */
+ for (rtr = policydb.range_tr; rtr; rtr = rtr->next) {
+ if (rtr->source_type == scontext->type &&
+ rtr->target_type == tcontext->type &&
+ rtr->target_class == tclass) {
+ /* Set the range from the rule */
+ return mls_range_set(newcontext,
+ &rtr->target_range);
}
}
/* Fallthrough */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f03960e697ce..b18895302555 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -96,6 +96,11 @@ static struct policydb_compat_info policydb_compat[] = {
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
+ {
+ .version = POLICYDB_VERSION_RANGETRANS,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_NUM,
+ },
};
static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -645,15 +650,15 @@ void policydb_destroy(struct policydb *p)
for (rt = p->range_tr; rt; rt = rt -> next) {
if (lrt) {
- ebitmap_destroy(&lrt->range.level[0].cat);
- ebitmap_destroy(&lrt->range.level[1].cat);
+ ebitmap_destroy(&lrt->target_range.level[0].cat);
+ ebitmap_destroy(&lrt->target_range.level[1].cat);
kfree(lrt);
}
lrt = rt;
}
if (lrt) {
- ebitmap_destroy(&lrt->range.level[0].cat);
- ebitmap_destroy(&lrt->range.level[1].cat);
+ ebitmap_destroy(&lrt->target_range.level[0].cat);
+ ebitmap_destroy(&lrt->target_range.level[1].cat);
kfree(lrt);
}
@@ -1829,6 +1834,7 @@ int policydb_read(struct policydb *p, void *fp)
}
if (p->policyvers >= POLICYDB_VERSION_MLS) {
+ int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS;
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
goto bad;
@@ -1847,9 +1853,16 @@ int policydb_read(struct policydb *p, void *fp)
rc = next_entry(buf, fp, (sizeof(u32) * 2));
if (rc < 0)
goto bad;
- rt->dom = le32_to_cpu(buf[0]);
- rt->type = le32_to_cpu(buf[1]);
- rc = mls_read_range_helper(&rt->range, fp);
+ rt->source_type = le32_to_cpu(buf[0]);
+ rt->target_type = le32_to_cpu(buf[1]);
+ if (new_rangetr) {
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
+ goto bad;
+ rt->target_class = le32_to_cpu(buf[0]);
+ } else
+ rt->target_class = SECCLASS_PROCESS;
+ rc = mls_read_range_helper(&rt->target_range, fp);
if (rc)
goto bad;
lrt = rt;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index b1340711f721..8319d5ff5944 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -106,9 +106,10 @@ struct cat_datum {
};
struct range_trans {
- u32 dom; /* current process domain */
- u32 type; /* program executable type */
- struct mls_range range; /* new range */
+ u32 source_type;
+ u32 target_type;
+ u32 target_class;
+ struct mls_range target_range;
struct range_trans *next;
};