Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3f87714 authored by Darrel Goeddel's avatar Darrel Goeddel Committed by Linus Torvalds
Browse files

[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: default avatarDarrel Goeddel <dgoeddel@trustedcs.com>
Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Acked-by: default avatarJames Morris <jmorris@namei.org>
Acked-by: default avatarEric Paris <eparis@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 016b9bdb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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;
+10 −11
Original line number Diff line number Diff line
@@ -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) {
		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,
					                     &rangetr->range);
				}
				                     &rtr->target_range);
			}
		}
		/* Fallthrough */
+20 −7
Original line number Diff line number Diff line
@@ -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;
+4 −3
Original line number Diff line number Diff line
@@ -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;
};